【发布时间】:2019-05-31 16:30:33
【问题描述】:
我想为条目i,j 创建一个矩阵,它返回D[i,1] 和D[j,1] 之间的最大值。
我有一个数字向量,在 MWE 中可以简化为:
set.seed(10)
n <- 2000
D <- matrix(runif(n,0,100), ncol=1)
在 Base R 中使用双 for 循环,效率极低:
X <- Matrix::Matrix(0, nrow = n, ncol = n, sparse = T)
for (i in 1:n) {
for (j in 1:n) {
X[i,j] <- max(D[i,1], D[j,1])
}
}
我也试过 dplyr:
library(dplyr)
X <- tibble(i = 1:n, D = D)
X <- expand.grid(i = 1:n, j = 1:n)
X <- X %>%
as_tibble() %>%
left_join(X, by = "i") %>%
left_join(X, by = c("j" = "i")) %>%
rowwise() %>%
mutate(D = max(D.x, D.y)) %>%
ungroup()
它在我可以做X <- Matrix::Matrix(X$D, nrow = n, ncol = n, sparse = T)之前返回Error: std::bad_alloc
我最后一次尝试是使用 RcppArmadillo 以使其也适用于 Windows:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
arma::mat pairwise_max(arma::mat x, arma::mat y) {
// Constants
int n = (int) x.n_rows;
// Output
arma::mat z(n,n);
// Filling with ones
z.ones();
for (int i=0; i<n; i++)
for (int j=0; j<=i; j++) {
// Fill the lower part
z.at(i,j) = std::max(y(i,0), y(j,0));
// Fill the upper part
z.at(j,i) = z.at(i,j);
}
return z;
}
它的工作原理几乎完美无缺,但我很确定有一种我看不到的基本 R 的有效方法。
【问题讨论】:
-
从基本 R 解决方案中删除
sparse矩阵。这是不必要的增长矩阵。只需使用matrix(0, nrow = n, ncol = n)。 -
Rcpp 解决方案将是最快的,因为这需要两个循环。