web-dev-qa-db-fra.com

Comment convertir une liste composée de vecteurs de différentes longueurs en un cadre de données utilisable en R?

J'ai une liste (assez longue) de vecteurs. Les vecteurs sont constitués de mots russes que j'ai obtenus en utilisant la fonction strsplit() sur des phrases.

Voici ce que head() renvoie: 

[[1]]
[1] "модно"     "создавать" "резюме"    "в"         "виде"     

[[2]]
[1] "ты"        "начианешь" "работать"  "с"         "этими"    

[[3]]
[1] "модно"            "называть"         "блогер-рилейшенз" "―"                "начинается"       "задолго"         

[[4]]
[1] "видел" "по"    "сыну," "что"   "он"   

[[5]]
[1] "четырнадцать," "я"             "поселился"     "на"            "улице"        

[[6]]
[1] "широко"     "продолжали" "род."

Notez que les vecteurs sont de longueur différente.

Ce que je veux, c'est pouvoir lire les premiers mots de chaque phrase, le deuxième mot, le troisième, etc. 

Le résultat souhaité ressemblerait à ceci: 

    P1              P2           P3                 P4    P5           P6
[1] "модно"         "создавать"  "резюме"           "в"   "виде"       NA
[2] "ты"            "начианешь"  "работать"         "с"   "этими"      NA
[3] "модно"         "называть"   "блогер-рилейшенз" "―"   "начинается" "задолго"         
[4] "видел"         "по"         "сыну,"            "что" "он"         NA
[5] "четырнадцать," "я"          "поселился"        "на"  "улице"      NA
[6] "широко"        "продолжали" "род."             NA    NA           NA

J'ai simplement essayé d'utiliser data.frame() mais cela n'a pas fonctionné car les lignes sont de longueur différente. J'ai aussi essayé rbind.fill() à partir du paquetage plyr, mais cette fonction ne peut traiter que les matrices. 

J'ai trouvé d'autres questions ici (c'est de là que j'ai obtenu l'aide de plyr), mais elles concernaient toutes la combinaison de deux images de taille différente. 

Merci de votre aide. 

39
Ico

essaye ça: 

Word.list <- list(letters[1:4], letters[1:5], letters[1:2], letters[1:6])
n.obs <- sapply(Word.list, length)
seq.max <- seq_len(max(n.obs))
mat <- t(sapply(Word.list, "[", i = seq.max))

le truc c'est que, 

c(1:2)[1:4]

renvoie le vecteur + deux NA

34
adibender

Une doublure avec plyr

plyr::ldply(Word.list, rbind)
70
Ramnath

Vous pouvez faire quelque chose comme ça:

## Example data
l <- list(c("a","b","c"), c("a2","b2"), c("a3","b3","c3","d3"))
## Compute maximum length
max.length <- max(sapply(l, length))
## Add NA values to list elements
l <- lapply(l, function(v) { c(v, rep(NA, max.length-length(v)))})
## Rbind
do.call(rbind, l)

Qui donne :

     [,1] [,2] [,3] [,4]
[1,] "a"  "b"  "c"  NA  
[2,] "a2" "b2" NA   NA  
[3,] "a3" "b3" "c3" "d3"
10
juba

Une autre option est stri_list2matrix de library(stringi)

library(stringi)
stri_list2matrix(l, byrow=TRUE)
#    [,1] [,2] [,3] [,4]
#[1,] "a"  "b"  "c"  NA  
#[2,] "a2" "b2" NA   NA  
#[3,] "a3" "b3" "c3" "d3"

NOTE: Données du post de @ juba.

Ou comme @Valentin mentionné dans les commentaires

sapply(l, "length<-", max(lengths(l)))
9
akrun

vous pouvez également utiliser rbindlist() de data.table-package.

Convertissez les vecteurs en data.table ou data.frame et transposez-le (pas sûr si cela réduit beaucoup la vitesse) à l'aide de lapply(). Ensuite, liez-les avec rbindlist() - remplissant les cellules manquantes avec NA:

l = list(c("a","b","c"), c("a2","b2"), c("a3","b3","c3","d3"))
dt = rbindlist(lapply(l, function(x) data.table(t(x))),
     fill = TRUE)
3
andrasz

Une autre option pourrait être de définir une fonction comme celle-ci (elle imiterait rbind.fill) ou de l’utiliser directement à partir du package rowr:

cbind.fill <- function(...){
  nm <- list(...) 
  nm <- lapply(nm, as.matrix)
  n <- max(sapply(nm, nrow)) 
  do.call(cbind, lapply(nm, function (x) 
    rbind(x, matrix(, n-nrow(x), ncol(x))))) 
}

Cordialement

0
jgarces