首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将一列分成两列

将一列分成两列
EN

Stack Overflow用户
提问于 2014-06-12 01:02:42
回答 4查看 866关注 0票数 0

我有一个很大的基因型data.table (26万行,1000列)。行是标记,列是主题。数据如下:

代码语言:javascript
复制
             ID1         ID2         ID3         ID4
M1:          CC          CC          TC          CC
M2:          GG          GG          GG          GG
M3:          TT          TT          TT          TT
M4:          TG          TG          TG          TG
M5:          TT          TT          TT          TT
M6:          TT          TT          TT          TT

我需要把每一种基因型分开,这样我才能在它自己的列中有这样的等位基因:

代码语言:javascript
复制
             V1 V2 V3 V4 V5 V6 V7 V8
        M1:  C  C  C  C  T  C  C  C
        M2:  G  G  G  G  G  G  G  G
        M3:  T  T  T  T  T  T  T  T
        M4:  T  G  T  G  T  G  T  G
        M5:  T  T  T  T  T  T  T  T
        M6:  T  T  T  T  T  T  T  T

我想出了两种解决方案,这两种解决方案都适用于数据的一个子集,但由于内存问题或data.table的某些内部错误,我无法理解,因此对整个数据集进行了分解。

  1. 我对每个列都使用了strsplit,并将其存储到一个列表中,然后使用do.call将它们全部合并。我还使用foreach函数并行化了它。 ids <- colname(DT) gene.split <- function(i) { as.data.table(do.call(rbind,do.call idsi)),split =“”)} all.gene <- foreach(i=1:length(Id)) %dopar% gene.split(i) do.call(cbind,all.gene)

在4个核心上,这是由于内存问题而崩溃的。

  1. 第二种解决方案基于类似的problem,它使用set函数: out_names <-粘贴(“V”,1:(2*ncol(DT),sep="_") invar1 <- name(DT)(seq_along(Invar1)中的i){ set(DT,i=NULL,j=out_name2*i-1,value=do.call(rbind,str拆分(DT[[invar1i],split =“”))集合(DT,i=NULL,j=out_names2*i,value=do.call(rbind,str拆分(DT[invar1i]),split =“”),2)}}

它可以在几个列上工作,但是如果我尝试使用整个数据集,则会得到以下错误:

集合中的错误(DT,i= NULL,j= out_names2 *i-1,value = do.call(rbind,:内部逻辑错误)。传递给赋值的DT没有分配足够的列槽。l=163,tl=163,添加1

我是不是走错路了?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-12 02:46:02

下面是一种使用data.table::setsubstr的方法(而不是str拆分)

使用@jbaum示例数据l

代码语言:javascript
复制
# coerce to `data.table` without a copy
setDT(l)
# over allocate columns so that `data.table` can assign by reference
# this will stop the error you were seeing
alloc.col(l,3000)


out_names <- paste("V", 1:(2*ncol(l)), sep="_")
invar1 <- names(l)

for (i in seq_along(invar1)) {
  set(l, i=NULL, j=out_names[2*i-1], value=substr(l[[invar1[i]]],1,1))
  set(l, i=NULL, j=out_names[2*i], value=substr(l[[invar1[i]]],2,2))
}

最后一步在我的Windows7 i7 2600机器上用了37秒,内存为8GB

在您的示例中,您运行了两次strsplit (并使用do.call(rbind....)) -->没有效率。

一些可能的分割方法的基准.

代码语言:javascript
复制
microbenchmark(substr(l[[invar1[1L]]],2,2), sapply(strsplit(l[[invar1[1L]]],''),`[`,2L),do.call(rbind, strsplit(l[[invar1[i]]], split = ""))[,2], times=5)
Unit: milliseconds
                                                      expr        min         lq     median         uq       max neval
                             substr(l[[invar1[1L]]], 2, 2)   14.10669   14.35571   14.57485   15.78283  193.9125     5
            sapply(strsplit(l[[invar1[1L]]], ""), `[`, 2L)  345.92969 1420.03907 1944.33873 3864.82876 5371.6130     5
 do.call(rbind, strsplit(l[[invar1[i]]], split = ""))[, 2] 3318.70878 4131.38551 4155.06126 5269.92745 8414.4948     5
票数 3
EN

Stack Overflow用户

发布于 2014-06-12 02:27:50

这里有一种相对较快的方法--花费了大约80秒(在虚拟数据创建之后) (Win 8.1 x64;i4770),但是消耗了13 GB的内存。

代码语言:javascript
复制
# Creating initial data 
pairs <- c(outer(c('C', 'T', 'G', 'A'), c('C', 'T', 'G', 'A'), 'paste0'))
l <- replicate(1000, sample(pairs, 260000, replace=TRUE), simplify=FALSE)

system.time({
  v <- do.call(paste0, l)
  rm(l); gc()
  out <- do.call(rbind, strsplit(v, ''))
  rm(v); gc()
})

#   user  system elapsed 
#  79.07    1.24   80.33 

str(out)

# chr [1:260000, 1:2000] "A" "C" "C" "C" ...
票数 2
EN

Stack Overflow用户

发布于 2014-06-12 02:11:40

下面是一种对数据帧x执行此操作的方法

代码语言:javascript
复制
do.call(cbind, 
        lapply(x, 
               function(i) do.call(rbind, strsplit(as.character(i), split=''))
        )
)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] "C"  "C"  "C"  "C"  "T"  "C"  "C"  "C" 
[2,] "G"  "G"  "G"  "G"  "G"  "G"  "G"  "G" 
[3,] "T"  "T"  "T"  "T"  "T"  "T"  "T"  "T" 
[4,] "T"  "G"  "T"  "G"  "T"  "G"  "T"  "G" 
[5,] "T"  "T"  "T"  "T"  "T"  "T"  "T"  "T" 
[6,] "T"  "T"  "T"  "T"  "T"  "T"  "T"  "T" 

每一列被分割成字符,然后r-绑定在一起.这将给出列的列表,然后将这些列传递给cbind

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24174986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档