Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
计算R中一个大矩阵的行和?_R_Bigdata_R Bigmemory - Fatal编程技术网

计算R中一个大矩阵的行和?

计算R中一个大矩阵的行和?,r,bigdata,r-bigmemory,R,Bigdata,R Bigmemory,我有一个大矩阵,大约有6000万行和150列(大约总共90亿个元素)。我已将此数据存储在一个big.matrix对象中(来自packagebigmemory)。现在,我想计算每一行的总和,这是一个问题,因为big.matrix是面向列的,所以据我所知,所有汇总函数都是面向列的(例如colsum,colmax,等等),默认情况下没有用于计算行总和的函数。当然我可以做应用(x,1,sum),但这需要很长时间。我还可以逐个循环列,并使用矢量化加法添加它们: mysum <- rep(0, nro

我有一个大矩阵,大约有6000万行和150列(大约总共90亿个元素)。我已将此数据存储在一个
big.matrix
对象中(来自package
bigmemory
)。现在,我想计算每一行的总和,这是一个问题,因为
big.matrix
是面向列的,所以据我所知,所有汇总函数都是面向列的(例如
colsum
colmax
,等等),默认情况下没有用于计算行总和的函数。当然我可以做
应用(x,1,sum)
,但这需要很长时间。我还可以逐个循环列,并使用矢量化加法添加它们:

mysum <- rep(0, nrow(x))
for (i in seq(ncol(x))) 
  mysum <- mysum + x[,i]

<代码> MySoo> p>我编写了一些C++代码来完成这一操作,从:

rowSums.cpp

// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>

#include <numeric>

// Logic for BigRowSums.
template <typename T>
NumericVector BigRowSums(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat) {
    NumericVector rowSums(pMat->nrow(), 0.0);
    NumericVector value(1);
    for (int jj = 0; jj < pMat->ncol(); jj++) {
      for (int ii = 0; ii < pMat->nrow(); ii++) {
        value = mat[jj][ii];
        if (all(!is_na(value))) {
          rowSums[ii] += value[0];
        }   
      }   
    }   
    return rowSums;
}

// Dispatch function for BigRowSums
//
// [[Rcpp::export]]
NumericVector BigRowSums(SEXP pBigMat) {
    XPtr<BigMatrix> xpMat(pBigMat);

    switch(xpMat->matrix_type()) {
      case 1:
        return BigRowSums(xpMat, MatrixAccessor<char>(*xpMat));
      case 2:
        return BigRowSums(xpMat, MatrixAccessor<short>(*xpMat));
      case 4:
        return BigRowSums(xpMat, MatrixAccessor<int>(*xpMat));
      case 6:
        return BigRowSums(xpMat, MatrixAccessor<float>(*xpMat));
      case 8:
        return BigRowSums(xpMat, MatrixAccessor<double>(*xpMat));
      default:
        throw Rcpp::exception("unknown type detected for big.matrix object!");
    }   
}
/[[Rcpp::depends(BH)]]
#包括
使用名称空间Rcpp;
//[[Rcpp::Dependes(BH,bigmemory)]]
#包括
#包括
//大行和的逻辑。
模板
数字向量大行和(XPtr pMat,MatrixAccessor mat){
数值向量行和(pMat->nrow(),0.0);
数值向量值(1);
对于(intjj=0;jjncol();jj++){
对于(int ii=0;iinrow();ii++){
价值=材料[jj][ii];
如果(全部(!为_na(值))){
行和[ii]+=值[0];
}   
}   
}   
返回行和;
}
//大行和的调度函数
//
//[[Rcpp::导出]]
数字向量BigRowSums(SEXP-pBigMat){
XPtr xpMat(pBigMat);
开关(xpMat->matrix_type()){
案例1:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例2:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例4:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例6:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例8:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
违约:
抛出Rcpp::异常(“为big.matrix对象检测到未知类型!”);
}   
}
在R:

library(bigmemory)
library(Rcpp)
sourceCpp("rowSums.cpp")

m <- as.big.matrix(matrix(1:9, 3))
BigRowSums(m@address)
[1] 12 15 18
库(大内存)
图书馆(Rcpp)
sourceCpp(“rowSums.cpp”)

m
rowSums
对它不起作用吗?您可以转置然后获取
colsum
吗?假设您有
数字
数据,您所指示的时间对应于大约60 MB/s的吞吐量(20分钟内72 GB数据=3.6 GB/min)。根据数据存储的位置,这可能非常接近物理限制。读取该文件需要多长时间(
time cp file>/dev/null
)?它不是R的数字类型。它是一个大的整数矩阵,所以我相信它在磁盘和内存中都存储得更紧凑。磁盘上的文件大约是30GB,我不知道当我加载它时,它是否会将整个矩阵加载到内存中。您不能一次对整个内容进行操作,因为其中包含的元素多于
.Machine$integer.max
元素。这就是为什么我把它放在一个
大的.matrix
中。您无法快速转换
大.matrix
。正如我所说,数据结构是面向列的,因此转置它必须完全重建整个数据结构。您可以随时修改
Rcpp
库中的代码,以执行
rowSums
,而不是
colSums
:这看起来很棒。如果它比我已经得到的(可能是)快,我会接受它作为答案。我曾尝试创建一个文件备份的大矩阵来测试它,但它使我的计算机停止运行(创建它),所以我杀死了它。我很想看看情况如何!你不能用艾根或犰狳吗?我认为即使在C++中,这样的嵌套循环也会非常快。