In this blog post , Paul Hiemstra 展示了如何使用 dplyr::mutate_
对两列求和。 .复制/粘贴相关部分:
library(lazyeval)
f = function(col1, col2, new_col_name) {
mutate_call = lazyeval::interp(~ a + b, a = as.name(col1), b = as.name(col2))
mtcars %>% mutate_(.dots = setNames(list(mutate_call), new_col_name))
}
允许然后做:
head(f('wt', 'mpg', 'hahaaa'))
伟大的!
我跟进了一个问题(见评论),关于如何将其扩展到 100 列,因为(对我而言)不太清楚如何在不必使用上述方法键入所有名称的情况下做到这一点。保罗很乐意放纵我并提供了这个答案(谢谢!):
# data
df = data.frame(matrix(1:100, 10, 10))
names(df) = LETTERS[1:10]
# answer
sum_all_rows = function(list_of_cols) {
summarise_calls = sapply(list_of_cols, function(col) {
lazyeval::interp(~col_name, col_name = as.name(col))
})
df %>% select_(.dots = summarise_calls) %>% mutate(ans1 = rowSums(.))
}
sum_all_rows(LETTERS[sample(1:10, 5)])
我想在以下几点上改进这个答案:
rowSums()
这必须将 data.frame 强制转换为我想避免的矩阵。另外我不确定是否使用
.
内非do()
鼓励动词?因为.
在 mutate()
内与 group_by()
一起使用时似乎并不能仅适应那些行. mutate_()
做同样的事情?而不是 mutate()
? 我找到了this answer ,它解决了第 1 点,但不幸的是,这两个
dplyr
答案使用 rowSums()
连同 mutate()
.PS:我刚看了Hadley's comment under that answer . IIUC, 'reshape to long form + group by + sum + reshape to wide form'是推荐
dplyr
这些类型的操作方式?
最佳答案
这是一种不同的方法:
library(dplyr); library(lazyeval)
f <- function(df, list_of_cols, new_col) {
df %>%
mutate_(.dots = ~Reduce(`+`, .[list_of_cols])) %>%
setNames(c(names(df), new_col))
}
head(f(mtcars, c("mpg", "cyl"), "x"))
# mpg cyl disp hp drat wt qsec vs am gear carb x
#1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 27.0
#2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 27.0
#3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 26.8
#4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 27.4
#5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 26.7
#6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 24.1
关于你的观点:
rowSums
group_by
如何使用 .
可能会造成任何伤害里面 mutate
/mutate_
mutate_
关于r - 使用 'mutate_' 逐行求和一堆列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32825662/