【问题标题】:Transpose list rows into a dataframe将列表行转置为数据框
【发布时间】:2018-01-27 00:13:06
【问题描述】:

假设这是我的列表结构

lst=list(structure(c("level1", "level2", "level4", "level5","18", "abc", "pqr", "lmn"),
         .Dim = c(4L, 2L)), 
     structure(c("level1", "level2", "level3", "level5", "level6", "20", "xyz", "hive", "foo", "bar"), 
        .Dim = c(5L, 2L)),
     structure(c("level1", "level3", "level4", "level5","level6", "22", "dark", "yellow","foobar", "blue"), 
        .Dim = c(5L, 2L)),
     structure(c("level1", "level2", "level3", "level5","level6","level7","24", "dvd", "dxs","glass", "while","though"), 
     .Dim = c(6L, 2L))
     )

期待这样的 O/P

     level1 level2  level3  level4  level5  level6  level7
1)     18       abc     NA      pqr     lmn     NA      NA
2)     20       xyz     hive    NA      foo     bar     NA
3)     22       NA      dark    yellow  foobar  blue    NA
4)     24       dvd     dxs     NA      glass   while   though  

所有列表的第一列应该被转置,相应的数据应该被查找到它们的行。

尝试将所有行转置到列本身给出错误

 unique(t(list_temp[[c(1,2)]][,1]))
ERROR:Error in list_temp[[c(1, 2)]][, 1] : incorrect number of dimensions

也试过

apply(list_temp,1,function(x){list_temp[[x]][,1]})

但是给了我

Error in apply(list_temp, 1, function(x) { : 
  dim(X) must have a positive length

关于如何完成的任何建议。

谢谢。

【问题讨论】:

    标签: r list dataframe lapply transpose


    【解决方案1】:

    两种方法:

    1) 使用-package

    与:

    library(data.table)
    dcast(rbindlist(lapply(lst, as.data.table), idcol = 'id'),
          id ~ V1, value.var = 'V2')[, id := NULL][]
    

    你得到:

       level1 level2 level3 level4 level5 level6 level7
    1:     18    abc     NA    pqr    lmn     NA     NA
    2:     20    xyz   hive     NA    foo    bar     NA
    3:     22     NA   dark yellow foobar   blue     NA
    4:     24    dvd    dxs     NA  glass  while though
    

    2) 使用基础 R

    与:

    reshape(transform(do.call(rbind.data.frame, lst),
                      r = rep(seq_along(lst), lengths(lst)/2)),
            idvar = 'r', timevar = 'V1', direction = 'wide')[,-1]
    

    你得到:

       V2.level1 V2.level2 V2.level4 V2.level5 V2.level3 V2.level6 V2.level7
    1         18       abc       pqr       lmn      <NA>      <NA>      <NA>
    5         20       xyz      <NA>       foo      hive       bar      <NA>
    10        22      <NA>    yellow    foobar      dark      blue      <NA>
    15        24       dvd      <NA>     glass       dxs     while    though
    

    【讨论】:

    • 那是如此的干净和优雅...+1 for rbindlist..感谢您的时间和精力!!!
    • 我认为您的代码中存在一些错误..如果我有 4 个列表记录而不是 2 个,那么它不会给出正确的输出。
    • @deepesh 您能否在您的问题中包含(添加)一个重现您的问题的示例?
    • 更新帖子
    • @deepesh 据我所知,它似乎对我有用,另请参阅新数据的更新答案。你能解释一下输出有什么问题吗?
    【解决方案2】:

    这是另一个想法,使用Reduce 合并数据帧,然后转置并进行一些清理,即

    m1 <- t(Reduce(function(...) merge(..., by = 'V1', all = TRUE), lapply(lst, as.data.frame)))
    colnames(m1) <- m1[1,]
    row.names(m1) <- NULL
    final_d <- as.data.frame(m1[-1,], stringsAsFactors = FALSE)
    

    给出,

       level1 level2 level4 level5 level3 level6 level7
    1     18    abc    pqr    lmn   <NA>   <NA>   <NA>
    2     20    xyz   <NA>    foo   hive    bar   <NA>
    3     22   <NA> yellow foobar   dark   blue   <NA>
    4     24    dvd   <NA>  glass    dxs  while though
    

    【讨论】:

    • 这也是一个很好的方法。感谢您的时间和精力!!!
    猜你喜欢
    • 2014-03-19
    • 2023-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 2020-04-17
    相关资源
    最近更新 更多