有没有办法插入新列,其中包含以特定文本开头的其他现有列的平均值?
例如,在此数据集中:
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 ......
答案 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)
)
首先,我们创建一个字符向量,其中包含我们想要一起平均的列的名称。以下代码将动态选择以20 _:
开头的所有列名to_aggregate = names(zz)[grepl("^20", names(zz))]
我们创建一个动态计算均值的公式:
agg_formula = as.formula(paste0(" ~ mean(c(", paste0("`", to_aggregate, "`", collapse = ", "), "))"))
这将创建公式: 〜表示(c(&#39; 20_1&#39;,&#39; 20_2&#39;,&#39; 20_3&#39;))
我们可以使用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))