如何在不丢失具有character(0)的行的情况下绑定行?

时间:2019-04-13 06:28:59

标签: r rbind

我有一个像L的列表(来自矢量分割)。

L <- strsplit(c("1 5 9", "", "3 7 11", ""), " ")

# [[1]]
# [1] "1" "5" "9"
# 
# [[2]]
# character(0)
# 
# [[3]]
# [1] "3"  "7"  "11"
# 
# [[4]]
# character(0)

当我按如下所述执行普通的rbind时,我将丢失所有的character(0)行。

do.call(rbind, L)
#      [,1] [,2] [,3]
# [1,] "1"  "5"  "9" 
# [2,] "3"  "7"  "11"

我是否总是必须像下面这样做lapply还是错过了什么?

do.call(rbind, lapply(L, function(x) 
    if (length(x) == 0)  rep("", 3) else x))
#      [,1] [,2] [,3]
# [1,] "1"  "5"  "9" 
# [2,] ""   ""   ""  
# [3,] "3"  "7"  "11"
# [4,] ""   ""   ""  

以R为基础的答案是首选。

5 个答案:

答案 0 :(得分:3)

如果使用lapply,则不必担心长度,因此可以跳过rep部分,该部分将自动在各列之间循环使用。

do.call(rbind, lapply(L, function(x) if (length(x) == 0)  "" else x))

#    [,1] [,2] [,3]
#[1,] "1"  "5"  "9" 
#[2,] ""   ""   ""  
#[3,] "3"  "7"  "11"
#[4,] ""   ""   ""  

另一种使用与@NelsonGon相同的逻辑的选项,我们可以将空白列表替换为空白,然后rbind

L[lengths(L) == 0] <- ""
do.call(rbind, L)

#    [,1] [,2] [,3]
#[1,] "1"  "5"  "9" 
#[2,] ""   ""   ""  
#[3,] "3"  "7"  "11"
#[4,] ""   ""   ""  

答案 1 :(得分:2)

也许使用data.table的环形交叉路口适合您:

L <- data.table::tstrsplit(c("1 5 9", "", "3 7 11", ""), " ", fill="")
t(do.call(rbind,L))

答案 2 :(得分:2)

使用plyr ,然后进行替换。由于OP要求提供基数R,请参见下文。

 plyr::ldply(L,rbind)
     1    2    3
1    1    5    9
2 <NA> <NA> <NA>
3    3    7   11
4 <NA> <NA> <NA>

低效的基本R方法:

 L <- strsplit(c("1 5 9", "", "3 7 11", ""), " ")
 L[lapply(L,length)==0]<-"Miss"
 res<-Reduce(rbind,L)
 res[res=="Miss"]<-""

结果:

     [,1] [,2] [,3]
init "1"  "5"  "9" 
     ""   ""   ""  
     "3"  "7"  "11"
     ""   ""   ""  

答案 3 :(得分:2)

我们可以简单地使用stri_list2matrix

library(stringi)
stri_list2matrix(L, byrow = TRUE, fill = "")
#   [,1] [,2] [,3]
#[1,] "1"  "5"  "9" 
#[2,] ""   ""   ""  
#[3,] "3"  "7"  "11"
#[4,] ""   ""   ""  

答案 4 :(得分:1)

这是类似情况的定义行为。如?rbind中所述:

  

对于cbind(rbind),长度为零(包括NULL)的向量将被忽略   除非结果具有零行(列),以确保S兼容性。   (零级矩阵在S3中不会出现,在R中不会被忽略。)

检查元素时,您会发现它是真实的:

length(L[[1]])

[1] 3

length(L[[2]])

[1] 0

但是,如您所见,可能有多种解决方法。