使用 `dplyr` 查找大 tibble 的 row-wise 均值和方差的最快方法是什么?

What is the fastest way to use `dplyr` to find the row-wise mean and variance of a large tibble?

我希望为数字小标题中的每一行生成均值和方差值。使用我现有的代码,我认为这是一个非常适合 dplyr 的解决方案,需要几个小时才能完成大约 35 列的 50,000 行。

有没有办法只使用 dplyr 来加速这个操作?我知道 apply 和 purrr 是选项,但我最好奇的是,在执行像这样的大量计算时,我是否忽略了 dplyr 的某些内容。

可重现的例子:

library(tidyverse)
library(vroom)
gen_tbl(50000, cols = 40, 
        col_types = paste0(rep("d", 40), collapse = "")) %>%
  rowwise() %>%
  mutate(mean = mean(c_across()),
         var = var(c_across()))

我怀疑 rowwise() 但我很感兴趣是否有更细微的方法可以用 dplyr 解决这个问题,或者这不是 dplyr 擅长的问题。

行向方法的处理时间似乎呈二次方增长:

旋转时间越长,计算速度大约快 300 倍。对于 50k 行,下面的代码用了 1.2 秒,而 rowwise 方法用了 372 秒。

df %>%
  mutate(row = row_number()) %>%
  tidyr::pivot_longer(-row) %>%
  group_by(row) %>%
  summarize(mean = mean(value),
            var = var(value)) %>%
  bind_cols(df, .)

如果你能得到像 matrixStats::rowVars() 这样的 row-wise 方差函数,你就可以做到这一点。我不确定为什么 c_across() 不这样做,但 across() 似乎有效。我从 this issue

得到的
library(tidyverse)
library(vroom)

gen_tbl(
  rows = 50000, 
  cols = 40, 
  col_types = paste0(rep("d", 40), collapse = "")
) %>%
  mutate(
    mean = rowMeans(across(everything())),
    # var = rowVars(across(everything())),
    .before = everything()
  )

# A tibble: 50,000 x 41
#    mean     X1     X2   
#    <dbl>  <dbl>  <dbl>  
# 1  0.199   -0.715 -1.64   
# 2 -0.212   -0.983 -1.38   
# 3  0.126   -0.135  0.263