【发布时间】:2015-09-28 14:35:38
【问题描述】:
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'))
太棒了!
我随后提出了一个问题(参见 cmets),即如何将其扩展到 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()动词中使用.?因为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(lazyeval)。