【问题标题】:R - unlist into dataframeR - 取消列表到数据框中
【发布时间】:2017-02-09 22:55:20
【问题描述】:

我在 R 中有一个向量列表:

[[1]]
[1] 1 2 3 4

[[2]]
[1] 7 9 1 4

[[3]]
[1] 8 2 1

[[4]]
[1] 8 9 0 7

我想用它们制作一个dataframe。问题是,我不能简单地使用 unlist 然后重新组织,因为并非所有向量的长度都相同——当这种情况发生时,我希望我的数据帧中有 NA。最终结果应如下所示:

Col1  Col2  Col3  Col4
1     2     3     4
7     9     1     4
8     2     1     NA
8     9     0     7

有没有办法做到这一点?

【问题讨论】:

标签: r vector dataframe


【解决方案1】:

使用purrr,您可以执行以下操作:

require(purrr)
L <- list(1:4, c(7,9,1,4), c(8,2,1), c(8,9,0,7))
map_df(L, ~as.data.frame(t(.)))

这给了你:

  V1 V2 V3 V4
1  1  2  3  4
2  7  9  1  4
3  8  2  1 NA
4  8  9  0  7

基础 R 方法:

clen <- vapply(L, length, integer(1))
mat <- matrix(NA, nrow = length(L), ncol = max(clen))
for(i in seq_along(L)){
  mat[i, seq(1, clen[i])] <- L[[i]]
}
as.data.frame(mat)

【讨论】:

    【解决方案2】:

    在基础 R 中试试这个(ls 是你的列表对象):

    data.frame(t(sapply(ls, function(x) x[1:max(lengths(ls))])))
    

    你的数据会给你什么:

    #  X1 X2 X3 X4
    #1  1  2  3  4
    #2  7  9  1  4
    #3  8  2  1 NA
    #4  8  9  0  7
    

    一般情况下c(1:5)[1:7]会给你

    #[1]  1  2  3  4  5 NA NA
    

    【讨论】:

      【解决方案3】:

      cbind.ts 将作用于不同长度的对象。使用它,我们可以获得以下单行基本解决方案:

      as.data.frame(t(unname(do.call("cbind", lapply(L, ts)))))
      

      给予:

        V1 V2 V3 V4
      1  1  2  3  4
      2  7  9  1  4
      3  8  2  1 NA
      4  8  9  0  7
      

      这也可以表示为 magrittr 管道:

      library(magrittr)
      
      L %>% 
        lapply(ts) %>% 
        do.call(what = "cbind") %>% 
        t %>% 
        unname %>% 
        as.data.frame
      

      注意:我们使用这个作为输入:

      L <- list(1:4, c(7, 9, 1, 4), c(8, 2, 1), c(8, 9, 0, 7))
      

      【讨论】:

        【解决方案4】:

        我们可以使用stringi中的stri_list2matrix并将modecharacter转换为integer

        library(stringi)
        m1 <- stri_list2matrix(L, byrow=TRUE)
        mode(m1) <- "integer"
        m1
        #      [,1] [,2] [,3] [,4]
        #[1,]    1    2    3    4
        #[2,]    7    9    1    4
        #[3,]    8    2    1   NA
        #[4,]    8    9    0    7
        

        matrix 可以用as.data.frame 转换成data.frame 所以

        as.data.frame(m1)
        

        数据

        L <- list(1:4, c(7, 9, 1, 4), c(8, 2, 1), c(8, 9, 0, 7))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-15
          • 2015-04-03
          • 1970-01-01
          相关资源
          最近更新 更多