整齐的行表示来自列的子集

时间:2019-02-11 10:21:24

标签: r row tidyverse

我想从一个数据框中的多个列中计算汇总变量。键入所有行名时这是可能的,但是我想使用starts_with()和类似的函数。即

df <- data.frame(A1 = rnorm(100, 0, 1),
                 A2 = rnorm(100, 0, 1),
                 A3 = rnorm(100, 0, 1),
                 B1 = rnorm(100, 0, 1),
                 B2 = rnorm(100, 0, 1))

有效方法:

library(tidyverse)
df %>% mutate(A = (A1 + A2 + A3)/3)
df %>% mutate(A = rowMeans(select(., A1:A3)))

但是,前者在汇总许多变量时会很烦人,而后者在汇总许多行时会很快变得非常慢。我怀疑必须有一个更快的解决方案。

什么不起作用:

df %>% mutate(A = mean(A1:A3))
df %>% group_by(row_number()) %>% mutate(A = mean(A1:A3))
df %>% group_by(row_number()) %>% mutate(A = mean(starts_with("A")))

所以我的问题是:是否有一种方法可以在mutate()中使用mean()等来计算行均值,理想情况下不必拼出每个变量?

3 个答案:

答案 0 :(得分:3)

Base R是我测试中最快的。
我将使用更大的数据框。

library(tidyverse)
library(microbenchmark)
library(ggplot2)

set.seed(1234)

n <- 1e4
df <- data.frame(A1 = rnorm(n, 0, 1),
                 A2 = rnorm(n, 0, 1),
                 A3 = rnorm(n, 0, 1),
                 B1 = rnorm(n, 0, 1),
                 B2 = rnorm(n, 0, 1))

mb <- microbenchmark(
  m1 = df %>% mutate(A = (A1 + A2 + A3)/3),
  m2 = df %>% mutate(A = rowMeans(select(., A1:A3))),
  m3 = df %>% mutate(A = reduce(.[, grepl("^A", names(.))], `+`) / ncol(.[, grepl("^A", names(.))])),
  m4 = rowMeans(df[, grep("^A", names(df))]),
  m5 = df[, grep("^A", names(df))] %>% rowMeans()
)

mb

autoplot(mb)

纯基本R方式更快,其次是基本R subset / dplyr管道。

答案 1 :(得分:2)

select函数中使用函数starts_with

df %>% mutate(A = rowMeans(select(., starts_with("A"))))

如果您在帮助中搜索select_helpers,还会发现更多信息。

答案 2 :(得分:2)

在我以前的版本中,我以为rowMeans是个问题,但实际上减慢了计算速度的是select的使用-最好坚持使用grep系列:< / p>

df %>% mutate(A = rowMeans(.[, grepl("^A", names(.))]))