2017-08-24 47 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

我覺得我設法做對了。請看我的解決方案:) –