2016-11-28 44 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