美文网首页
R语言-超大型数据框与稀疏矩阵的切片-处理as.matrix方法

R语言-超大型数据框与稀疏矩阵的切片-处理as.matrix方法

作者: 倪桦 | 来源:发表于2022-06-27 18:41 被阅读0次

单细胞组学数据分析接触到的项目大都使用平面文件(rds,txt,tsv,csv,mtx)进行数据存储。有时候,我们会操作相当大的平面文件,而超大型的数据集如(一个包含约 100 万个细胞和约 3 万个基因的表达矩阵)在进行数据类型转换等处理的时候会遇到异常Error in asMethod(object) : Cholmod error 'problem too large',指的是其中 as.matrix() 转换常规矩阵,导致内存溢出。这个问题意味着处理数据的维度超过as.matrix()方法支持的最大矩阵维度(2147483647 (2^{31}-1))

本文提出一种在R里面将超大数据集切块用as.matrix()方法处理,再转换超大数据框和稀疏矩阵方法(as.spM_DFas.DF_spM)。
该数据分块的处理方式简单便捷,代码量少,不涉及其它语言,虽然牺牲了一些效率,但能有效避免内存溢出问题。

0、测试数据生成

getData <- function(n=100,is.str=FALSE,data.class="data.frame"){
    data.retro = data.frame(
        value = ceiling(runif(n = n,min = -1,max = 1)),
        norm = rnorm(n=n,mean=10,sd=1),
        expr = rexp(n),
        No = seq(n)
    )
    if (is.str) {data.retro = cbind(data.retro,strings = stringi::stri_rand_strings(n, 5, pattern = "[A-Za-z0-9]"))}
    switch (data.class,
            data.frame = {data.frame},
            matrix = {as.matrix(data.frame)}
    )
    return(data.retro)
}

1、 超大型稀疏矩阵转换出数据框

as.spM_DF <- function(data.use,chun_size=20000000) {
    lapply(  split(seq(nrow(data.use)), (seq(nrow(data.use))-1) %/% as.numeric(chun_size) )  , function(nx) {
        if ( is.null(nrow(data.use[nx,])) ) {
            as.data.frame(t(as.matrix(data.use[nx,])))
        }else{
            as.data.frame(as.matrix(data.use[nx,]))
        }
    }) %>% dplyr::bind_rows()
}

方法调用: as.spM_DF(as(as.matrix(getData(100)),"dgCMatrix"))

2、 超大型数据框转换出稀疏矩阵

as.DF_spM <- function(data.use,chun_size="20000000",sparseClass="dgCMatrix") {
    lapply(  split(seq(nrow(data.use)), (seq(nrow(data.use))-1) %/% as.numeric(chun_size) )  , function(nx) {
        switch(sparseClass,
               dgTMatrix = {as(as.matrix(data.use[nx,]),"dgTMatrix")},
               dgCMatrix = {as(as.matrix(data.use[nx,]),"dgCMatrix")},
               dgRMatrix = {as(as.matrix(data.use[nx,]),"dgRMatrix")},
               stop("Enter one of the three types of sparse matrix(\"dgTMatrix\",\"dgCMatrix\",\"dgRMatrix\")")
               )
        }) %>% Matrix.utils::rBind.fill()
}

方法调用 : as.DF_spM(getData(100),sparseClass = "dgTMatrix")

3、 分块写出超大型数据框

write_big_DF <- function(data.use,chun_size="20000000",file = "text.tsv",sep="\t",col.names=F,row.names=T,quote=F){
    ### first write colnames
    if (col.names) {write.table(x = data.use[0,],file = file,sep = sep,quote = quote,append = F,row.names = row.names,col.names = T)}
    lapply(  split(seq(nrow(data.use)), (seq(nrow(data.use))-1) %/% as.numeric(chun_size) )  , function(nx) {
        ### append content
        write.table(x = data.use[nx,],file = file,sep = sep,quote = quote,append = T,row.names = row.names,col.names = F)
    }) -> . ;rm(.)
}

方法调用 :write_big_DF(getData(10,is.str = T),chun_size = 3,file = "text.tsv",col.names=T,row.names = F)

相关文章

网友评论

      本文标题:R语言-超大型数据框与稀疏矩阵的切片-处理as.matrix方法

      本文链接:https://www.haomeiwen.com/subject/sgkwvrtx.html