dplyr中的mutate_each:使用其他列的平均行值创建新列,其中一些文本是共同的

时间:2016-05-16 15:56:38

标签: r dplyr

有没有办法插入新列,其中包含以特定文本开头的其他现有列的平均值?

例如,在此数据集中:

zz <-("
id  20_1    20_2    20_3    22_1    22_2    22_3    
1   .      4.00     3.50    5.80    5.35    5.15    
2   3.50    .       3.30    5.65    5.40    5.05    
3   2.80    3.40    3.80    5.30    5.25    5.30    
")

df <- read.table(text=zz, header = TRUE)

我想创建两个新列20_4和22_4,其平均行值分别为20_1:20_3和22_1:22_3 ......

id  20_1    20_2    20_3    20_4    22_1    22_2    22_3    22_4
1   NA      4.00    3.50    3.75    5.80    5.35    5.15    5.43
2   3.50    NA      3.30    3.40    5.65    5.40    5.05    5.37
3   2.80    3.40    3.80    3.33    5.30    5.25    5.30    5.28

有人可以帮助我吗?我还在学习dplyr ......

2 个答案:

答案 0 :(得分:0)

对此的优雅解决方案可能是使用非标准评估:

让我们考虑一个类似于你的df:

zz = data_frame(
  `20_1` = rnorm(5),
  `20_2` = rnorm(5),
  `20_3` = rnorm(5),
  `22_1` = rnorm(5),
  `22_2` = rnorm(5),
  `22_3` = rnorm(5)
)
  1. 首先,我们创建一个字符向量,其中包含我们想要一起平均的列的名称。以下代码将动态选择以20 _:

    开头的所有列名
    to_aggregate = names(zz)[grepl("^20", names(zz))]
    
  2. 我们创建一个动态计算均值的公式:

    agg_formula = as.formula(paste0(" ~ mean(c(", paste0("`", to_aggregate, "`", collapse = ", "), "))"))
    

    这将创建公式: 〜表示(c(&#39; 20_1&#39;,&#39; 20_2&#39;,&#39; 20_3&#39;))

  3. 我们可以使用dplyr逐行进行并应用上面生成的动态公式:

    zz %>% 
      mutate(tmp_ID = row_number()) %>% 
      group_by(tmp_ID) %>% 
      mutate_(.dots = setNames(list(agg_formula), 'res')) %>% 
      mutate(check_res = (`20_1` + `20_2` + `20_3`) / 3) %>% 
      ungroup()
    

答案 1 :(得分:0)

另一种方法是在dplyr中使用'summarize'来创建你想要的变量

zznew<-zz %>%
  group_by(id)%>%
  summarize("20_4"=mean(`20_1`:`20_3`,na.rm=TRUE),"22_4"=mean(`22_1`:`22_3`,na.rm=TRUE))%>%
  left_join(zz,zznew,by="id")

编辑:回想起来认为我说'使用'总结'是不正确的。这是一种不同的方法,它将计算所选列的每一行的均值并将它们绑定到数据帧:

zzz<-cbind(zz,"20_4"=rowMeans(zz[,c("20_1","20_2","20_3")],na.rm=TRUE),
      "22_4"=rowMeans(zz[,c("22_1","22_2","22_3")],na.rm=TRUE))