Есть ли более эффективный способ памяти использовать combn для вычитания каждого столбца из любого другого столбца в R? - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь вычесть каждый столбец из каждого другого столбца в большой R data.table, который имеет 13125 столбцов и 90 строк.

Я продолжаю работу над предыдущим вопросом, в котором рассматривается этот вопрос для таблиц данных меньших размеров ( Вычитает каждый столбец из каждого другого столбца в R data.table ).

Моя проблема в том, что в настоящее время у меня недостаточно памяти для генерации результирующей таблицы данных из комбинаций столбцов (для которой, по-видимому, требуется 59,0 ГБ).

У меня вопрос: есть ли более эффективный способ вычисления различий в столбцах с помощью 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="_")

Прошу прощения, если этот вопрос слишком похож и поэтому считается дублированием.Я был бы очень признателен за любые советы о том, как повысить эффективность этого кода для масштаба моих данных.

1 Ответ

0 голосов
/ 20 февраля 2019

В соответствии с комментарием ОП относительно следующего шага после разностных столбцов будет более компактно, если вы также возведете в квадрат и суммируете итоговые значения столбцов во время вычисления, так что в результате вы получите только вектор с 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  .....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...