【问题标题】:R tidy row means from subset of columns [duplicate]R整齐的行意味着来自列的子集[重复]
【发布时间】:2019-07-04 19:34:05
【问题描述】:

我想计算数据框中多列的汇总变量。这在输入所有行名时是可能的,但我想使用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() 等来计算行均值,理想情况下不必拼出每个变量?

【问题讨论】:

    标签: r row tidyverse


    【解决方案1】:

    在你的select函数中使用函数starts_with

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

    如果您搜索select_helpers 的帮助,您会发现更多。

    【讨论】:

    • 感谢您的回答。这基本上是我的第二个“有效”示例,除了使用starts_with()。不幸的是,这很快就会变得非常慢,所以我希望有一个更快的解决方案。
    • 对不起,我错过了表演部分!
    【解决方案2】:

    在我以前的版本中,我认为rowMeans 是问题所在,但实际上导致计算速度变慢的是select 的使用——最好还是坚持grep 系列:

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

    【讨论】:

      【解决方案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 子集/dplyr 管道。

      【讨论】:

      • 不错的基准!不会对性能产生太大影响,但应注意,对于相同的输出 %&gt;% cbind(df, A = .)(或类似的东西)需要添加到 m4m5
      • @arg0naut 或%&gt;% bind_cols(df, A = .),使用dplyr 函数。
      猜你喜欢
      • 2017-11-13
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-02
      相关资源
      最近更新 更多