2016-11-28 49 views
1

當你group_by多個變量時,dplyr有用地找到這些組的交集。dplyr :: group_by()有多個變量但不是交點

例如,

mtcars %>% 
    group_by(cyl, am) %>% 
    summarise(mean(disp)) 

產生

Source: local data frame [6 x 3] 
Groups: cyl [?] 

    cyl am `mean(disp)` 
    <dbl> <dbl>  <dbl> 
1  4  0  135.8667 
2  4  1  93.6125 
3  6  0  204.5500 
4  6  1  155.0000 
5  8  0  357.6167 
6  8  1  326.0000 

我的問題是,是否有提供多個變量,但總結輕微的方法嗎?我想要的輸出就像你所得到的一樣,如果你手工操作,可變的變量。

df_1 <- 
    mtcars %>% 
    group_by(cyl) %>% 
    summarise(est = mean(disp)) %>% 
    transmute(group = paste0("cyl_", cyl), est) 

df_2 <- 
    mtcars %>% 
    group_by(am) %>% 
    summarise(est = mean(disp)) %>% 
    transmute(group = paste0("am_", am), est) 

bind_rows(df_1, df_2) 

上面的代碼產生

# A tibble: 5 × 2 
    group  est 
    <chr> <dbl> 
1 cyl_4 105.1364 
2 cyl_6 183.3143 
3 cyl_8 353.1000 
4 am_0 290.3789 
5 am_1 143.5308 

理想情況下,語法會像

mtcars %>% 
group_by(cyl, am, intersection = FALSE) %>% 
summarise(est = mean(disp)) 

難道這樣的事情在tidyverse存在嗎?

(PS,我得到我的上表group變量不是的,因爲它包含一個兩個變量的意義整潔,但我保證我的目的很整潔,OK?:))

回答

4

我猜你在找什麼是tidyr包...

gather首先複製數據集,以便有n行用於每個因素將發生分組; mutate然後創建分組變量。

library(dplyr) 
library(tidyr) 

mtcars %>% 
    gather(col, value, cyl, am) %>% 
    mutate(group = paste(col, value, sep = "_")) %>% 
    group_by(group) %>% 
    summarise(est = mean(disp)) 
+0

這是一個很好的解決方案。小編輯使更一般 df%>% gather(col,value,X1,X2,X3,X4)%>% mutate(group = paste0(col,「_」,value)) –

+0

同意,答案 – denrou

1

purrr替代:

library(tidyverse) 

map(c('cyl', 'am'), 
    ~ mtcars %>% 
     group_by_(.x) %>% 
     summarise(est = mean(disp)) %>% 
     transmute_(group = lazyeval::interp(~paste0(.x, '_', y), y = as.name(.x)), 
       ~est)) %>% 
    bind_rows() 
# A tibble: 5 × 2 
    group  est 
    <chr> <dbl> 
1 cyl_4 105.1364 
2 cyl_6 183.3143 
3 cyl_8 353.1000 
4 am_0 290.3789 
5 am_1 143.5308