首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有动态列输入的逐行列的乘积-向量化操作

具有动态列输入的逐行列的乘积-向量化操作
EN

Stack Overflow用户
提问于 2019-04-11 19:57:27
回答 2查看 104关注 0票数 3

为了更有效地处理,我想将下面的代码向量化。我需要逐行获取列的乘积(即rowProds),但是我想要的列的数量需要是另一个输入的函数。

如果可能的话,我更希望使用Base来完成这项工作,但我愿意接受并欣赏任何建议。

这可以很容易地使用循环或应用家庭的udf,但这些不够快,以满足我的需要。

代码语言:javascript
复制
# Generate some data

mat <- data.frame(X = 1:5)
for (i in 1:5) {
  set.seed(i)
  mat[1 + i] <- runif(5)
}

# Via a for loop

for (i in 1:nrow(mat)) {  
  mat$calc[i] <- prod(mat[match(mat$X[i], mat$X), 2:(i + 1)])
}
mat

# Via a function with mapply

rowprodfun <- function(X) {  
  myprod <- prod(mat[match(X, mat$X), 2:(X + 1)])
  return(myprod)
}

mat$calc <- mapply(rowprodfun, mat$X)
mat

mat$calc
# [1] 0.265508663 0.261370165 0.126427355 0.013874517 0.009758232

上述两种方法的结果都是相同的"calc“列。我只需要一种更有效的方法来生成这个专栏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-11 21:12:10

一种选择是将上三角元素转换为NA,然后使用来自matrixStatsrowProds

代码语言:javascript
复制
library(matrixStats)
rowProds(as.matrix(mat[-1] * NA^upper.tri(mat[-1])), na.rm = TRUE)
#[1] 0.265508663 0.261370165 0.126427355 0.013874517 0.009758232
票数 1
EN

Stack Overflow用户

发布于 2019-04-15 22:59:38

@akrun建议使用upper.tri是非常有用的。最后一部分是在按元素进行乘法之前,将data.frame转换为矩阵as.matrix

rowProds(as.matrix(mat[-1]) * NA ^ upper.tri(mat[-1]), na.rm = T)的计算效率最高。

如果试图在R基地完成的话,apply(as.matrix(mat[-1]) * NA ^ upper.tri(mat[-1]), 1, prod, na.rm = T)几乎是同样有效的。

代码语言:javascript
复制
library(microbenchmark)
library(matrixStats)
library(ggplot2)

Y <- microbenchmark(
  for.loop = for (i in 1:nrow(mat)) {prod(mat[match(mat$X[i], mat$X), 2:(i + 1)])},
  mapply.fun = mapply(rowprodfun, mat$X),
  rowProds = rowProds(as.matrix(mat[-1] * NA ^ upper.tri(mat[-1])), na.rm = T),
  rowProds.matrix = rowProds(as.matrix(mat[-1]) * NA ^ upper.tri(mat[-1]), na.rm = T),
  apply = apply(mat[-1] * NA ^ upper.tri(mat[-1]), 1, prod, na.rm = T),
  apply.matrix = apply(as.matrix(mat[-1]) * NA ^ upper.tri(mat[-1]), 1, prod, na.rm = T)
)

> Y
Unit: microseconds
            expr      min        lq      mean    median        uq       max neval
        for.loop 4094.869 4305.5590 5682.2124 4479.8125 5193.8190 50361.025   100
      mapply.fun  542.962  577.6995 1036.9821  599.2220  658.1245 32426.296   100
        rowProds  518.419  553.9120  654.2657  597.5225  637.1690  2434.267   100
 rowProds.matrix   99.304  116.1065  144.9313  128.0010  153.8650   516.909   100
           apply  547.493  580.1540  686.2317  628.2955  703.0565  1215.812   100
    apply.matrix  117.051  136.6845  158.3808  144.9920  156.5075   339.068   100

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55640244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档