我正在尝试从大型R data.table中的每一列中减去每一列,该表具有13125列和90行。
我正在跟踪先前的问题,该问题针对较小尺寸(Subtract every column from each other column in a R data.table)的data.tables解决了此问题。
我的问题是我当前内存不足,无法生成列组合的data.table表(似乎需要59.0GB)。
我的问题是,对于大数据集,有没有一种更有效的内存计算方式来使用combin或其他函数来计算列差异?
我一直在使用的代码是:
# I have a data.table of 13125 columns and 90 rows, called data.
# use combn to generate all possible pairwise column combinations (column + column),
# then within this apply a function to subtract the column value from its paired column value.
# this is done for each row, to produce a new datatable called res.
res <- as.data.table(combn(colnames(data), 2, function(x) data[[x[1]]] - data[[x[2]]]))
# take the pairwise column combinations and paste the pairing as the new column name
colnames(res) <- combn(colnames(data), 2, paste, collapse="_")
如果这个问题太相似,因此我认为是重复的,我表示抱歉。我将非常感谢您提供有关如何针对我的数据规模提高此代码效率的任何建议。
答案 0 :(得分:0)
根据OP关于区分列之后下一步的注释,如果您在计算过程中也对列的总数求平方并求和,则将使内存更紧凑,从而结果将只有一个包含13,125个元素的向量,而不是存储13,125 * 90 * 90数字减法值。一种快速可行的方法是使用RcppArmadillo
:
colpairs.cpp
(绝不是唯一的实现):
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
rowvec colpairs(mat Z) {
unsigned int i, j, k = Z.n_cols;
colvec vi, vj, y;
rowvec res(k);
for (i=0; i<k; i++) {
vi = Z.col(i);
res[i] = 0;
for (j=0; j<k; j++) {
vj = Z.col(j);
y = vi - vj;
res[i] += as_scalar(y.t() * y);
}
}
return res;
}
在R中:
library(Rcpp)
library(RcppArmadillo)
sourceCpp("colpairs.cpp")
# #use a small matrix to check results
# set.seed(0L)
# nc <- 3; nr <- 3; M <- matrix(rnorm(nr*nc), ncol=nc)
# c(sum((M[,1]-M[,2])^2 + (M[,1]-M[,3])^2), sum((M[,3]-M[,2])^2 + (M[,2]-M[,3])^2), sum((M[,3]-M[,1])^2 + (M[,2]-M[,3])^2))
# colpairs(M)
set.seed(0L)
nc <- 13125
nr <- 90
M <- matrix(rnorm(nr*nc), ncol=nc)
colpairs(M)
trunc。输出:
[1] 2105845 2303591 2480945 2052415 2743199 2475948 2195874 2122436 2317515 .....