对于以下两个矩阵,
yy=matrix(c(1:40), nrow = 10, ncol = 8)
tt=diag(1:4)
我想通过将yy_new=matrix(NA, nrow = 10, ncol=ncol(tt))
的每一行和第一个4 column
乘以yy
来创建新的矩阵tt
。例如,对于第一行yy_new=yy[1,1:4]%*%tt
,第二行是yy_new=yy[2,1:4]%*%tt
。最后,我希望每列的yy_new
平均值为yy_new=apply(yy_new,2,mean)
。跟随循环运行良好,但是对于大数据集,这很费时间。
yy_new=matrix(NA, nrow = 10, ncol=ncol(tt))
for ( it in 1:10){
for ( tim in 1:4){
yy_new[it, tim]=yy[it,tim]*tt[tim,tim]
}
}
yy_new=apply(yy_new,2,mean)
类似地,通过考虑yy_new1
的最后四列,我想要另一个矩阵yy
yy_new1=matrix(NA, nrow = 10, ncol=ncol(tt))
如何使用任何内置功能或自定义功能有效地做到这一点?任何帮助表示赞赏。
这里是yy_new
的较短(更快)版本>
yy_new <- rowMeans(apply(yy[, 1:4], 1, function(row) row %*% tt))
类似地
yy
的最后四列
yy_new1 <- rowMeans(apply(yy[, (ncol(yy)-3):ncol(yy)], 1, function(row) row %*% tt))
请注意,
rowMeans
和colMeans
通常比apply(..., 1, mean)
和apply(..., 2, mean)
快。
这里是microbenchmark
比较的结果
library(microbenchmark) res <- microbenchmark( rowMeans_apply = { yy_new = rowMeans(apply(yy[, 1:4], 1, function(row) row %*% tt)) }, for_loop = { yy_new=matrix(NA, nrow = 10, ncol=ncol(tt)) for ( it in 1:10){ for ( tim in 1:4){ yy_new[it, tim]=yy[it,tim]*tt[tim,tim] } } } ) res #Unit: microseconds # expr min lq mean median uq max neval # rowMeans_apply 73.148 82.097 116.8959 101.329 123.863 1348.141 100 # for_loop 3985.521 4141.633 5017.9808 4421.285 5020.425 18574.364 100
更新
根据您的评论,您可以执行以下操作:
f <- function(x) rowMeans(apply(x, 1, function(row) row %*% tt)) sapply(split.default(as.data.frame(yy), rep(1:2, each = 4)), f) # 1 2 #[1,] 5.5 5.5 #[2,] 31.0 31.0 #[3,] 76.5 76.5 #[4,] 142.0 142.0
说明:
split.default
在这里将data.frame
分为前4列和后4列,并将它们作为两个data.frame
存储在list
中;然后我们使用sapply
遍历list
元素并根据请求计算所需的数量。结果输出对象是matrix
。