ggplot集锦

R循环追加数据到数据框

2020-07-20  本文已影响0人  生信云笔记

list转化为data.frame

  在数据处理过程中会遇到各式各样的要求,格式转换、数据结构重构等需求可以说是家常便饭了,所以R语言本身也提供了很多数据格式转换的函数或者第三个的包,如基础函数as.vector、as.list、as.data.frame等,这些函数都可以将数据转换为相应的格式,或者使用相应的包来实现。不过有时候对于自己的数据,基础的函数没法满足要求,本身挺容易实现的,又不想浪费很多时间上网找R包,这个时候就得自己来实现了,毕竟做分析还是要学会一些数据处理的技巧来应对这些尴尬的时刻。比如我最近在研究分析单细胞的R包metacell时,就遇到了一个问题,我想把其中的结果(嵌套list)转化为data.frame存储下来,基础函数没法完成,又不知道有没有其他能实现的包,只能靠自己了。。。
  废话不多说,下面来看看我的具体要求和实现过程。首先来看一下原始的嵌套list内容:

#从summary命令的结果可以看出列表mc_sup包含6个子列表
> summary(mc_sup)
     Length Class  Mode
[1,] 7      -none- list
[2,] 7      -none- list
[3,] 7      -none- list
[4,] 7      -none- list
[5,] 7      -none- list
[6,] 7      -none- list
#用str命名查看一下列表mc_sup的结构,可得知内部的子列表结构结构一致都是包含7个元素的list
>str(mc_sup)
List of 6
 $ :List of 7
  ..$ marks         : Named num [1:20] 1.25 1.26 1.26 1.33 1.34 ...
  .. ..- attr(*, "names")= chr [1:20] "PIK3IP1" "LTB" "CD247" "CD2" ...
  ..$ min_marks     : Named num [1:20] 1.02 1.04 1.08 1.18 1.25 ...
  .. ..- attr(*, "names")= chr [1:20] "PRKCQ-AS1" "CD27" "CD2" "CD6" ...
  ..$ marks_gap     : Named num [1:20] 1.25 1.27 1.27 1.31 1.36 ...
  .. ..- attr(*, "names")= chr [1:20] "LCK" "RPS18" "RCAN3" "RPS27" ...
  ..$ marks_gap_anti: Named num [1:20] -3.57 -3.36 -3.09 -2.92 -2.63 ...
  .. ..- attr(*, "names")= chr [1:20] "HLA-DRA" "S100A9" "S100A8" "CD74" ...
  ..$ mcs           : int [1:2] 2 1
  ..$ x_ord         : num 1.5
  ..$ sup_mcs       : int [1:10] 8 7 9 10 6 5 4 3 2 1
 $ :List of 7
  ..$ marks         : Named num [1:20] 1.45 1.53 1.63 1.73 1.76 ...
  .. ..- attr(*, "names")= chr [1:20] "CST7" "ARL4C" "GNLY" "GZMM" ...
  ..$ min_marks     : Named num [1:20] 0.744 0.748 0.749 0.808 0.87 ...
  .. ..- attr(*, "names")= chr [1:20] "GZMM" "PRKCH" "ZAP70" "PRKCQ-AS1" ...
  ..$ marks_gap     : Named num [1:20] 1.72 1.73 1.78 1.83 1.86 ...
  .. ..- attr(*, "names")= chr [1:20] "ARL4C" "GZMM" "TRBC1" "CD247" ...
  ..$ marks_gap_anti: Named num [1:20] -4.66 -4.44 -4.1 -3.44 -3.21 ...
  .. ..- attr(*, "names")= chr [1:20] "HLA-DRA" "S100A9" "S100A8" "CD74" ...
  ..$ mcs           : int [1:4] 4 3 2 1
  ..$ x_ord         : num 2.5
  ..$ sup_mcs       : int [1:10] 8 7 9 10 6 5 4 3 2 1

#现在需要把上面的列表mc_sup输出为数据框,格式如下:
> marks_info[1,1:3]
  id  mcs  sup_mcs  x_ord  marks   min_marks  marks_gap  marks_gap_anti  
1  2,1  8,7,6,5,4,3,2,1  1.5  PIK3IP1:1.251;LTB:1.256;  PRKCQ-AS1:1.017;CD27:1.039;   LCK:1.252;RPS18:1.261;  DPA1:-2.62;CTSS:-2.42;

代码实现

  大家应该明白我的具体实现要求了吧,就是把内层list的内容都变成数据框对应的一列,可以外层list有6个元素,内层list有7个元素,外层list的元素顺序变成数据框的id内容,最终转化为6行X8列的数据框。其中带字段‘marks’的列要复杂一点,需要将gene名和对应的值用‘:’链接起来,不同的gene用‘; ’分割,比如"CST7:1.45; ARL4C:1.53"。格式的转换的问题解决了,下面就是如何循环向data.frame里面循环写入数据了,我这里采用先第一个空的数据框,然后将数据与其合并,如此循环下去来实现,下面是具体的代码:

#这里定义了一个函数,两个参数分别为上面所说的嵌套list和输出文件名
>export_marks_tab <- function(mc_sup,outname){
   df <- data.frame()  #此处一个空的数据框
   for(i in 1:length(mc_sup)){
      mcs <- paste(mc_sup[[i]]$mcs,collapse=',')
      sup_mcs <- paste(mc_sup[[i]]$sup_mc,collapse=',')
      x_ord <- mc_sup[[i]]$x_ord
      marks <- paste(names(mc_sup[[i]]$marks),mc_sup[[i]]$marks,sep=':',collapse='; ')
      min_marks <- paste(names(mc_sup[[i]]$min_marks),mc_sup[[i]]$min_marks,sep=':',collapse='; ')
      marks_gap <- paste(names(mc_sup[[i]]$marks_gap),mc_sup[[i]]$marks_gap,sep=':',collapse=';')
      marks_gap_anti <- paste(names(mc_sup[[i]]$marks_gap_anti),mc_sup[[i]]$marks_gap_anti,sep=':',collapse='; ')
      #此处采用行合并的方式将数据与空的数据框合并,相当于向数据框追加数据,然后生成的数据框替代原先的数据框
      df <- rbind(df,data.frame(id=i,mcs=mcs,sup_mcs=sup_mcs,x_ord=x_ord,marks=marks,min_marks=min_marks,marks_gap=marks_gap,marks_gap_anti=marks_gap_anti))
   }
   write.table(df,outname,quote=F,row.names=F,col.names=T,sep='\t')
}
#调用函数
>export_marks_tab(mc_sup,'pbmc_hcluster_info.txt')

最后

  写一个自定的函数就可以完成需求了,写成函数方便调用和代码复用,是不是很简单,你学会了么?各位看官们记得帮忙点赞啊!!!😉😉😉

上一篇下一篇

猜你喜欢

热点阅读