Как связать строки, не теряя строки с символом (0)? - PullRequest
5 голосов
/ 13 апреля 2019

У меня есть список типа 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,] ""   ""   ""  

Ответы Base R предпочтительнее.

Ответы [ 5 ]

3 голосов
/ 13 апреля 2019

Если вы используете 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,] ""   ""   ""  
2 голосов
/ 13 апреля 2019

Мы можем использовать stri_list2matrix простым способом

library(stringi)
stri_list2matrix(L, byrow = TRUE, fill = "")
#   [,1] [,2] [,3]
#[1,] "1"  "5"  "9" 
#[2,] ""   ""   ""  
#[3,] "3"  "7"  "11"
#[4,] ""   ""   ""  
2 голосов
/ 13 апреля 2019

С plyr, затем продолжить замену. Поскольку ОП запросил базу 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"
     ""   ""   ""  
2 голосов
/ 13 апреля 2019

Может быть, этот перекресток с использованием data.table вам подходит:

L <- data.table::tstrsplit(c("1 5 9", "", "3 7 11", ""), " ", fill="")
t(do.call(rbind,L))
1 голос
/ 13 апреля 2019

Это определенное поведение для подобных сценариев.Как написано в ?rbind:

Для cbind (rbind) векторы нулевой длины (включая NULL) игнорируются, если результат не будет иметь нулевых строк (столбцов) для совместимости с S.(Матрицы нулевого экстента не встречаются в S3 и не игнорируются в R.)

Когда вы проверяете свои элементы, вы видите, что это правда:

length(L[[1]])

[1] 3

length(L[[2]])

[1] 0

ОднакоКак видите, возможно несколько обходных путей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...