在这篇博客文章中,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强制转换为matrix,我希望避免这种情况。此外,我不确定在非
do()
动词中使用.
是否被鼓励。因为当与group_by()
一起使用时,mutate()
中的.
似乎不仅适用于那些行。最重要的是,如何使用
mutate_()
而不是mutate()
来完成相同的工作?
我找到了这个答案,它解决了第一点,但不幸的是,两个dplyr
答案都使用了rowSums()
和mutate()
。
PS: 我刚刚阅读了那个答案下的Hadley的评论。如果我理解正确,“重塑为长格式+按组合并+求和+重塑为宽格式”是这类操作的推荐dplyr
方法吗?
library(lazyeval)
。 - Konrad Rudolph