使用列表中的唯一元素提取数据框

时间:2012-10-31 08:12:10

标签: r list dataframe

嗨,我有一个这样的清单

$`2`
  chr.pos  nt.pos CNV GRP
      1  783605   1   2
      1  888149   1   2
      1  991311   1   2
      1 1089305   1   2
      1 1177669   1   2

$`4`
 chr.pos  nt.pos CNV GRP
      2 1670488   1   4
      2 1758800   1   4

$`6`
 chr.pos  nt.pos CNV GRP
      2 1902924   1   6
      2 1978088   1   6

我想提取每个元素,独特的染色体,CNV和组以及最高和最低的nt.pos,所以输出将是,我更喜欢数据框

chr.pos  Start     End       GRP
 1         783605    1177669   2
 2         1670488   175880    4
 2         1902924   1978088   6

我试过这个

results<-lapply(mylist, function(x){

return(as.data.frame(unique(x$chr.pos),range(x$nt.pos)[1],range(x$nt.pos)  [2],unique(x$GRP)))

}
) 

但当然,我得到的是一份清单。

你能帮我吗?

3 个答案:

答案 0 :(得分:3)

假设您的列表名为“dat”,如下所示:

dat <- read.table(header = TRUE, text = "chr.pos  nt.pos CNV GRP
1  783605   1   2
1  888149   1   2
1  991311   1   2
1 1089305   1   2
1 1177669   1   2
2 1670488   1   4
2 1758800   1   4
2 1902924   1   6
2 1978088   1   6")
dat <- split(dat, dat$GRP)

首先,一个问题:你真的需要它作为list,还是只需要很长data.frame?如果必须保留列表,可以尝试以下方法:

  1. sapply()

    data.frame(t(sapply(dat, function(x) 
      data.frame(chr.pos = unique(x["chr.pos"]), 
                 Start = min(x["nt.pos"]), 
                 End = max(x["nt.pos"]), 
                 GRP = unique(x["GRP"])))))
    
  2. lapply()

    do.call(rbind, lapply(dat, function(x) 
      data.frame(chr.pos = unique(x["chr.pos"]), 
                 Start = min(x["nt.pos"]), 
                 End = max(x["nt.pos"]), 
                 GRP = unique(x["GRP"]))))
    
  3. 两者都会导致:

    #   chr.pos   Start     End GRP
    # 2       1  783605 1177669   2
    # 4       2 1670488 1758800   4
    # 6       2 1902924 1978088   6
    

    其次,如果它可能很长data.frame,那么请探索data.table()

    library(data.table)
    DaT <- data.table(do.call(rbind, dat), key = "GRP")
    DaT[, list(chr.pos = unique(chr.pos),
               Start = min(nt.pos),
               End = max(nt.pos)), by = key(DaT)]
    #    GRP chr.pos   Start     End
    # 1:   2       1  783605 1177669
    # 2:   4       2 1670488 1758800
    # 3:   6       2 1902924 1978088
    

答案 1 :(得分:1)

这就是诀窍:(假设dat是您的数据框列表。)

structure(
    as.data.frame(cbind(do.call(rbind,
                                lapply(dat,
                                       function(x) c(x[["chr.pos"]][1], 
                                                     range(x[["nt.pos"]])))),
                        as.numeric(names(dat)))),
    .Names = c("chr.pos", "Start", "End", "GRP"))

#   chr.pos   Start     End GRP
# 2       1  783605 1177669   2
# 4       2 1670488 1758800   4
# 6       2 1902924 1978088   6

答案 2 :(得分:0)

谢谢Sven,

我使用此

以类似的方式做到了
N <- length(results)  #
DF <- data.frame(chr=rep(NA, N), Start=rep(NA, N), End=rep(NA,N), Group=rep(NA,N), stringsAsFactors=FALSE)

for (i in 1:length(results)){

  DF[i, ] <- c(unique(results[[i]]$chr.pos), range(results[[i]]$nt.pos)[1], range(results[[i]]$nt.pos)[2],unique(results[[i]]$GRP))

}