如何避免循环*数据框中多行的乘法

How to avoid loop in *multiplication of multiple rows in data frame

这应该是一个简单的。 A是一个数据框。我正在尝试一直计算 A[1,]*A[2,]*A[3,]***。有没有办法不用 for 循环?提前致谢!

我们可以使用sapply来取列乘积

sapply(A, prod)

#  a   b   c 
#  6 120 504 

colProds 来自 matrixStats

matrixStats::colProds(as.matrix(A))

数据

A <- data.frame(a = 1:3, b = 4:6, c = 7:9)

首先让我们创建一些要使用的数据:

set.seed(1)
A <- matrix(runif(1e8), ncol = 100, nrow = 10000)

# Same as A just a data.frame for sapply()
B <- as.data.frame(A)

A是一个矩阵(matrixStats::colProdsRfast::colprods的矩阵运算所必需的)。 B 与用于 sapply 的 data.frame 是同一个矩阵。每种方法的适用性显然取决于您的用例。

@Ronak Shah提出了以下两种方法

sapply(B, prod)
matrixStats::colProds(A)

@dc37 在您原来的 post

的评论中提出了这个建议
apply(A, 2, prod)

第三种解决方案是使用 Rfast 包。

Rfast::colprods(A)

我们可以对每种方法进行基准测试以了解它们的表现:

microbenchmark::microbenchmark(sapply(B, prod),
            matrixStats::colProds(A),
            Rfast::colprods(A),
            apply(A, 2, prod))

我们看到 apply()matrixStats::colProds()sapply()Rfast::colprods() 提供的解决方案慢。如果您只执行一次操作,那没关系,但如果您多次执行此操作(例如在循环或要优化的函数内),那么时间差异可能会增加。

Unit: microseconds
                     expr    min      lq     mean  median     uq     max neval
          sapply(B, prod) 1199.3 1227.90 1329.564 1242.45 1273.9  4597.9   100
 matrixStats::colProds(A) 2445.5 2490.60 2967.945 2540.05 2740.4  8351.9   100
       Rfast::colprods(A)  723.4  738.45  854.042  750.25  767.7  4867.4   100
        apply(A, 2, prod) 4759.5 4828.50 5351.112 4872.15 5012.6 21006.0   100

summarise_all 来自 dplyr

的选项
library(dplyr)
A %>%
   summarise_all(prod)
#  a   b   c
#1 6 120 504

数据

A <- data.frame(a = 1:3, b = 4:6, c = 7:9)