R循環(huán)追加數(shù)據(jù)到數(shù)據(jù)框

list轉(zhuǎn)化為data.frame

??在數(shù)據(jù)處理過程中會(huì)遇到各式各樣的要求,格式轉(zhuǎn)換、數(shù)據(jù)結(jié)構(gòu)重構(gòu)等需求可以說是家常便飯了,所以R語言本身也提供了很多數(shù)據(jù)格式轉(zhuǎn)換的函數(shù)或者第三個(gè)的包,如基礎(chǔ)函數(shù)as.vector、as.list、as.data.frame等,這些函數(shù)都可以將數(shù)據(jù)轉(zhuǎn)換為相應(yīng)的格式,或者使用相應(yīng)的包來實(shí)現(xiàn)。不過有時(shí)候?qū)τ谧约旱臄?shù)據(jù),基礎(chǔ)的函數(shù)沒法滿足要求,本身挺容易實(shí)現(xiàn)的,又不想浪費(fèi)很多時(shí)間上網(wǎng)找R包,這個(gè)時(shí)候就得自己來實(shí)現(xiàn)了,畢竟做分析還是要學(xué)會(huì)一些數(shù)據(jù)處理的技巧來應(yīng)對(duì)這些尷尬的時(shí)刻。比如我最近在研究分析單細(xì)胞的R包metacell時(shí),就遇到了一個(gè)問題,我想把其中的結(jié)果(嵌套list)轉(zhuǎn)化為data.frame存儲(chǔ)下來,基礎(chǔ)函數(shù)沒法完成,又不知道有沒有其他能實(shí)現(xiàn)的包,只能靠自己了。。。
??廢話不多說,下面來看看我的具體要求和實(shí)現(xiàn)過程。首先來看一下原始的嵌套list內(nèi)容:

#從summary命令的結(jié)果可以看出列表mc_sup包含6個(gè)子列表
> 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的結(jié)構(gòu),可得知內(nèi)部的子列表結(jié)構(gòu)結(jié)構(gòu)一致都是包含7個(gè)元素的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

#現(xiàn)在需要把上面的列表mc_sup輸出為數(shù)據(jù)框,格式如下:
> 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;

代碼實(shí)現(xiàn)

??大家應(yīng)該明白我的具體實(shí)現(xiàn)要求了吧,就是把內(nèi)層list的內(nèi)容都變成數(shù)據(jù)框?qū)?yīng)的一列,可以外層list有6個(gè)元素,內(nèi)層list有7個(gè)元素,外層list的元素順序變成數(shù)據(jù)框的id內(nèi)容,最終轉(zhuǎn)化為6行X8列的數(shù)據(jù)框。其中帶字段‘marks’的列要復(fù)雜一點(diǎn),需要將gene名和對(duì)應(yīng)的值用‘:’鏈接起來,不同的gene用‘; ’分割,比如"CST7:1.45; ARL4C:1.53"。格式的轉(zhuǎn)換的問題解決了,下面就是如何循環(huán)向data.frame里面循環(huán)寫入數(shù)據(jù)了,我這里采用先第一個(gè)空的數(shù)據(jù)框,然后將數(shù)據(jù)與其合并,如此循環(huán)下去來實(shí)現(xiàn),下面是具體的代碼:

#這里定義了一個(gè)函數(shù),兩個(gè)參數(shù)分別為上面所說的嵌套list和輸出文件名
>export_marks_tab <- function(mc_sup,outname){
   df <- data.frame()  #此處一個(gè)空的數(shù)據(jù)框
   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='; ')
      #此處采用行合并的方式將數(shù)據(jù)與空的數(shù)據(jù)框合并,相當(dāng)于向數(shù)據(jù)框追加數(shù)據(jù),然后生成的數(shù)據(jù)框替代原先的數(shù)據(jù)框
      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')
}
#調(diào)用函數(shù)
>export_marks_tab(mc_sup,'pbmc_hcluster_info.txt')

最后

??寫一個(gè)自定的函數(shù)就可以完成需求了,寫成函數(shù)方便調(diào)用和代碼復(fù)用,是不是很簡(jiǎn)單,你學(xué)會(huì)了么?各位看官們記得幫忙點(diǎn)贊?。。?!??????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容