【问题标题】:Using 'mutate_' to sum a bunch of columns row-wise使用 'mutate_' 对一堆列进行逐行求和
【发布时间】: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)])

我想在以下几点上改进这个答案:

  1. 其他列已消失。我想保留它们。

  2. 它使用rowSums(),它必须将 data.frame 强制转换为我想避免的 matrix

    我也不确定是否鼓励在 do() 动词中使用.?因为mutate() 中的. 在与group_by() 一起使用时似乎并不只适应那些行。

  3. 最重要的是,我怎样才能使用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)

标签: r dplyr


【解决方案1】:

这是一种不同的方法:

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
  • 您在这里特别要求逐行操作,所以我不确定(还)在mutate/mutate_ 中使用.group_by 会造成什么伤害
  • 它利用mutate_

【讨论】:

  • 太棒了!在.group_by() 上,我觉得很奇怪。作为一个示例,计算行总和并将它们除以组内的最大总和。我猜你首先计算行总和,然后分组并得到比率?如果是这样,我觉得很奇怪(无法使用 mutate 一步完成,而是使用 do())。但也许这是设计使然,不用担心。谢谢。
  • 嗨@docendo discimus。很好的答案。你知道在最近发布的 dplyr 中是否有一些函数可以添加一个列作为匹配某个正则表达式的列的总和?
猜你喜欢
  • 1970-01-01
  • 2018-05-15
  • 2015-09-20
  • 2020-06-14
  • 1970-01-01
  • 2018-05-27
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多