0

我正在尝试从大型 R data.table 中的每一列中减去每一列,该表有 13125 列和 90 行。

我正在跟进上一个问题,该问题针对较小尺寸的 data.tables 解决了这个问题(从 R data.table 中的每一列中减去每一列)。

我的问题是我目前内存不足,无法生成列组合的结果 data.table(这似乎需要 59.0GB)。

我的问题是,是否有一种更节省内存的方法来计算使用 combn 或更大数据集的另一个函数的列差异?

我一直在使用的代码是:

# 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="_")

如果这个问题太相似并因此被视为重复,我深表歉意。对于如何针对我的数据规模提高此代码的效率的任何建议,我将不胜感激。

4

1 回答 1

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)

截断。输出:

[1] 2105845 2303591 2480945 2052415 2743199 2475948 2195874 2122436 2317515  .....
于 2019-02-20T08:16:21.193 回答