美文网首页
列表转数据框-我的计算机还能救一救

列表转数据框-我的计算机还能救一救

作者: Stone_Stan4d | 来源:发表于2018-12-08 18:04 被阅读32次

我曾经有一个表,它叫lncmiRcode,它这么大:

> dim(lncmiRcode)
[1] 208303      3

你没看错,它只有3列,但是有20.8万行
它来自于另一个更大的表miRcode, 128.6w行 * 12列:

# 只保留lncRNA
tmpIndex = miRcode$gene_class %in% 
  c('lncRNA, intergenic', 'lncRNA, overlapping', 'pseudogene')
lncmiRcode = miRcode[tmpIndex,c(2, 3, 4)]
lncmiRcode = dplyr::distinct(lncmiRcode)#去除重复的行
image.png
这些都不重要,重要的是,它的第三列是不规范的,用一个/就把两个不同的miRNA给打发了,是几个意思呢?
image.png
我要把这些miRNA分离出来,让它们各自占用一行,像这样:
 gene_symbol gene_class    microrna
1        MYH16 pseudogene       miR-7
2        MYH16 pseudogene     miR-7ab
3        MYH16 pseudogene  miR-133abc
4        MYH16 pseudogene      miR-96
5        MYH16 pseudogene     miR-507
6        MYH16 pseudogene    miR-1271
7        MYH16 pseudogene   miR-135ab
8        MYH16 pseudogene miR-135a-5p
9        MYH16 pseudogene     miR-138
10       MYH16 pseudogene   miR-138ab

其实这些小分子(miRNA)的前缀是不一样的,有let,有/miR

tmp = substr(lncmiRcode$microrna, 1, 3) 
> table(tmp)
tmp
   let    miR 
  1952 206351 

把冰箱装进大象一共有几步呢?


先打开冰箱,分开绑到一起的miRNAs:

  tmpmiR= strsplit(lncmiRcode$microrna, split = '/') 
#用'/'绑到一起,就用'/'分开
  for(i in 1:length(tmpmiR)){
    miRs = tmpmiR[i][[1]]
    if(length(miRs) > 1){
    # 如果有绑到一起的情况,就执行{}内代码,改变tmpmiR[[i]]的内容
      miRs[2:length(miRs)] = paste(tmp[i], miRs[2:length(miRs)],  sep = '-')
    #加上存在tmp里的前缀,当然用i来一一对应
      tmpmiR[i][[1]] = miRs}
    }
tmpmiR lncmiRcode

是不是一一对应?


接下来把大象塞进冰箱,让分开的miRNA去于lncRNA配对,且形成数据框:

#先构造一个函数,实现把绑一起的miRNA合成一组,
#因为它们靶向相同的lncRNA,然后组成数据框
  tmpfun = function(i){
    tmpRow = data.frame(gene_symbol = unlist(rep(lncmiRcode[i, 1], length(tmpmiR[[i]]))),
                        gene_class = unlist(rep(lncmiRcode[i, 2], length(tmpmiR[[i]]))),
                        microrna = tmpmiR[[i]])
    return(tmpRow)
    }

#再用神奇的lapply,对'lncmiRcode'中的每一个元素,实行该函数,#这样就把大象装进冰箱啦!
  tmpMat = lapply(1:length(tmpmiR), tmpfun)

如果事情到此就结束了,我还有必要写一个笔记记下来吗?问题在哪里?

返回的tmpMat,是一个list,而不是data.frame:

> tmpMat[1:3]
[[1]]
  gene_symbol gene_class microrna
1       MYH16 pseudogene    miR-7
2       MYH16 pseudogene  miR-7ab

[[2]]
            gene_symbol gene_class   microrna
gene_symbol       MYH16 pseudogene miR-133abc

[[3]]
  gene_symbol gene_class microrna
1       MYH16 pseudogene   miR-96
2       MYH16 pseudogene  miR-507
3       MYH16 pseudogene miR-1271

昨天,我用了一个for循环,这么长的list,循环了有15~20min吧,显然我是不愿意的:

  for(i in 1:length(tmpMat)){
    tmpMat0 = rbind(tmpMat0, tmpMat[[i]])
  }
  
  lncmiRcode = lncmiRcode[!grepl('/', lncmiRcode$microrna),]
  lncmiRcode = rbind(lncmiRcode, tmpMat0)
  save(lncmiRcode, file = 'lncRNA-miR-miRcode.rdata')

第三步,关上冰箱,把藏在list里的data.frame整理出来:
搜索如此:

image.png
第四条解释
image.png
image.png
image.png
image.png

看得出来,data.table::rbind.list()函数是最快的。我自己尝试一下看看:

data = tmpMat[1:5000]


library(rbenchmark)
benchmark(do.call(rbind, data), ldply(data, rbind), rbind.fill(data), 
          rbind_all(data), rbindlist(data))
> benchmark(do.call(rbind, data), ldply(data, rbind), rbind.fill(data), 
+           rbind_all(data), rbindlist(data))
                  test replications elapsed relative user.self sys.self user.child
1 do.call(rbind, data)          100    4.30   71.667      4.27     0.00         NA
2   ldply(data, rbind)          100   12.08  201.333     11.97     0.00         NA
3     rbind.fill(data)          100    6.50  108.333      5.97     0.03         NA
4      rbind_all(data)          100    0.31    5.167      0.30     0.00         NA
5      rbindlist(data)          100    0.06    1.000      0.06     0.00         NA
  sys.child
1        NA
2        NA
3        NA
4        NA
5        NA
There were 50 or more warnings (use warnings() to see the first 50)

我选择用这个data.table::rbindlist,运行很快,一秒不到:

tmpMat0 = data.table::rbindlist(tmpMat)
> head(tmpMat0)
   gene_symbol gene_class   microrna
1:       MYH16 pseudogene      miR-7
2:       MYH16 pseudogene    miR-7ab
3:       MYH16 pseudogene miR-133abc
4:       MYH16 pseudogene     miR-96
5:       MYH16 pseudogene    miR-507
6:       MYH16 pseudogene   miR-1271

关于benchmark:
Benchmark Experiments

相关文章

  • 列表转数据框-我的计算机还能救一救

    我曾经有一个表,它叫lncmiRcode,它这么大: 你没看错,它只有3列,但是有20.8万行它来自于另一个更大的...

  • 你那么丧,应该还能救一救!

    其实他这个人挺丧的, 为什么? 因为他会莫名其妙的不想说话, 莫名其妙的就一个人发呆, 莫名其妙的就不回人消息, ...

  • 2020-11-10

    一切痛苦皆是因为心苦,心念一转心情舒畅。救人先救心,救心救思维。

  • 紫色酢浆草

    妈妈,妈妈,快过来! 咋啦? 我把菜都摘下来了,你炒了吧! 啊……我可怜的,紫色酢浆草,心爱的花 ,还能再救一救吗?!

  • R基础-列表list()

    列表类型用来保存不同类型的数据,实际上,数据框也是列表的一种,但是数据框要求各列等长, 而列表不要求。 语法 列表...

  • 2018-01-20

    我救不了他们,也救不了自己

  • 毛孔粗大别放弃,还能用精油救一救

    我做了什么,让毛孔变大了? 毛孔粗大的原因有很多种,让小u为你揭开毛孔为什么会粗大的真相~ 1、光老化 紫外线里的...

  • R基础三(数据框)

    数据框 数据框是一种表格式的数据结构,通常是由数据构成的一个矩形数组,行表示观测,列表示变量。数据框实际是一个列表...

  • 污染的细胞:我还想救一救

    原文来自微信公众号小张聊科研。打赌不出一个月,链接会失效,flag: 2018.11.17。为此搬运到简书,不怕微...

  • 一个年轻女子的自述

    十个海子救不了这世 十个孩子救不了这世 残暴的天使救不了 善良的魔鬼也救不了 生锈的金钱救不了 自卑的权力也救不了...

网友评论

      本文标题:列表转数据框-我的计算机还能救一救

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