2017-08-24 144 views
3

考虑这个简单的例子如何用lm,do,broom和dplyr组来计算回归?

> dataframe <- data_frame(id = c(1,2,3,4,5,6), 
+       group = c(1,1,1,2,2,2), 
+       value = c(200,400,120,300,100,100)) 
> dataframe 
# A tibble: 6 x 3 
    id group value 
    <dbl> <dbl> <dbl> 
1  1  1 200 
2  2  1 400 
3  3  1 120 
4  4  2 300 
5  5  2 100 
6  6  2 100 

在这里,我想在一个恒定的使用回归value,受group组。我有get_mean()功能

get_mean <- function(data, myvar){ 
    col_name <- as.character(substitute(myvar)) 
    fmla <- as.formula(paste(col_name, "~ 1")) 
    tidy(lm(data = data,fmla)) %>% pull(estimate) 
} 

简易方法:

dataframe %>% group_by(group) %>% mutate(bug = get_mean(., value), 
             Ineedthis = max(value)) 

# A tibble: 6 x 5 
# Groups: group [2] 
    id group value  bug Ineedthis 
    <dbl> <dbl> <dbl> <dbl>  <dbl> 
1  1  1 200 203.3333  400 
2  2  1 400 203.3333  400 
3  3  1 120 203.3333  400 
4  4  2 300 203.3333  300 
5  5  2 100 203.3333  300 
6  6  2 100 203.3333  300 

失败,因为你可以看到平均按组进行计算。

这是众所周知的,使用do将工作。

dataframe %>% group_by(group) %>% do(bug = get_mean(., value)) 
Source: local data frame [2 x 2] 
Groups: <by row> 

# A tibble: 2 x 2 
    group  bug 
* <dbl> <list> 
1  1 <dbl [1]> 
2  2 <dbl [1]> 

不过,我不知道如何使用do得到其他Ineedthis变量,我不知道如何选择不公开的bug变量。我想我的输出是:

# A tibble: 6 x 5 
    id group value good   Ineedthis 
    <dbl> <dbl> <dbl> <dbl>  <dbl> 
1  1  1 200 240   400 
2  2  1 400 240   400 
3  3  1 120 240   400 
4  4  2 300 166.6666  300 
5  5  2 100 166.6666  300 
6  6  2 100 166.6666  300 

任何想法?谢谢!!

+1

也许用'unnest' – akrun

+0

感谢@akrun,但我怎么也弄了'Ineedthis'变量?你有没有工作解决方案?谢谢!! –

回答

0

这是一个很酷的解决方案,可以重现预期的输出。不知道它的更好的解决方案,但仍然值得与我的编码爱好者分享:)

get_output <- function(dataframe){ 
temp <- dataframe %>% 
    group_by(group) %>% 
    do({mymean = get_mean(., value); 
     myother = max(.$value); 
     dplyr::data_frame(mean = mymean, 
         other = myother)}) 
dataframe %>% left_join(temp) 
    } 


    > get_output(dataframe) 
Joining, by = "group" 
# A tibble: 6 x 5 
    id group value  mean other 
    <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  1 200 240.0000 400 
2  2  1 400 240.0000 400 
3  3  1 120 240.0000 400 
4  4  2 300 166.6667 300 
5  5  2 100 166.6667 300 
6  6  2 100 166.6667 300 
2

我做了一些更改get_mean功能,但它在功能上做同样的事情。请参阅:

get_mean <- function(., myvar){ 
    dat <- substitute(myvar) %>% data.frame(.) %>% setNames('vec') 
    out <- lm(data = dat,'vec ~ 1')$coefficients[1] %>% unname(.) 
    return(out) 
} 

允许我们这样做:

dataframe %>% 
    group_by(group) %>% 
    summarise(good = get_mean(., value), Ineedthis= max(value)) %>% 
    left_join(dataframe, ., by = 'group') 

,导致:

id group value  good Ineedthis 
1 1  1 200 240.0000  400 
2 2  1 400 240.0000  400 
3 3  1 120 240.0000  400 
4 4  2 300 166.6667  300 
5 5  2 100 166.6667  300 
6 6  2 100 166.6667  300 
+0

感谢@Zach,但我需要保持该功能,因为它在别处使用。此外,我认为这是一个很好的机会,在这里使用'do'而不是总结,你不认为 –

+1

@NOOBIE你可以添加一个包装函数到'get_mean'吗? – Zach

+0

我觉得我设法做对了。请看我的解决方案:) –