我有一个像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为基础的答案是首选。
答案 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
但是,如您所见,可能有多种解决方法。