1
votes

Comment convertir une liste de vecteurs de longueur inégale en une trame de données

J'ai besoin de convertir la liste suivante en un bloc de données:

    P01 P02 P03 P04 P05 P06 P07 P08 P09 P10 P11 P12
D01 13  5   9   16  1   7   3   20  NA  NA  NA  NA
D02 0   1   2   7   8   14  20  NA  NA  NA  NA  NA
D03 2   4   7   9   12  14  16  NA  NA  NA  NA  NA

... and so on

La liste a la structure suivante:

List of 1
 $ :List of 12
  ..$ : int [1:8] 13 5 9 16 1 7 3 20
  ..$ : int [1:7] 0 1 2 7 8 14 20
  ..$ : int [1:7] 2 4 7 9 12 14 16
  ..$ : int [1:10] 0 1 2 3 4 5 6 7 8 9
  ..$ : int [1:10] 18 19 20 21 22 23 6 7 8 9
  ..$ : int [1:10] 0 1 7 13 19 6 12 18 2 8
  ..$ : int [1:2] 23 22
  ..$ : int [1:3] 18 13 8
  ..$ : int [1:10] 18 13 8 3 10 17 12 6 0 1
  ..$ : int [1:2] 18 14
  ..$ : int [1:10] 18 19 20 21 13 7 8 14 2 1
  ..$ : int [1:10] 13 15 16 9 8 7 14 20 19 18

Parce que chaque vector peut être composé de 12 entiers, je souhaite convertir cette liste en un bloc de données qui ressemble à ceci:

list(c(13, 5, 9, 16, 1, 7, 3, 20), c(0, 1, 2, 7, 8, 14, 20), c(2, 4, 7, 9, 12, 14, 16), 0:9, c(18, 19, 20, 21, 22, 23, 6, 7, 8, 9), c(0, 1, 7, 13, 19, 6, 12, 18, 2, 8), 23:22, c(18, 13, 8), c(18, 13, 8, 3, 10, 17, 12, 6, 0, 1), c(18, 14), c(18, 19, 20, 21, 13, 7, 8, 14, 2, 1), c(13, 15, 16, 9, 8, 7, 14, 20, 19, 18))

Tous les conseils à corriger qui sont grandement appréciés.


1 commentaires

data.table :: rbindlist (lapply (d, function (x) setNames (data.frame (t (x)), paste0 ("P", seq_along (x)))), fill = TRUE)


3 Réponses :


5
votes

En supposant que votre liste de listes s'appelle x , vous pouvez utiliser

sapply(1:12, function(i) sapply(x, `[`, i))

pour obtenir les données souhaitées. Ici, nous parcourons les différents index que vous souhaitez extraire de chaque vecteur. Cela arrive juste en R lorsque vous demandez une position qui n'existe pas, vous obtenez NA . Il vous suffit d'ajouter des noms de ligne / colonne avec les valeurs souhaitées.


0 commentaires

2
votes

Vous pouvez le faire en modifiant la longueur des vecteurs originaux dans la liste. Le's appelle la liste a

dimnames(res) <- list(sprintf("D%02i", 1:nrow(res)), 
                     sprintf("P%02i", 1:ncol(res)))
res
# P01 P02 P03 P04 P05 P06 P07 P08 P09 P10
# D01  13   5   9  16   1   7   3  20  NA  NA
# D02   0   1   2   7   8  14  20  NA  NA  NA
# D03   2   4   7   9  12  14  16  NA  NA  NA
# D04   0   1   2   3   4   5   6   7   8   9
# D05  18  19  20  21  22  23   6   7   8   9
# D06   0   1   7  13  19   6  12  18   2   8
# D07  23  22  NA  NA  NA  NA  NA  NA  NA  NA
# D08  18  13   8  NA  NA  NA  NA  NA  NA  NA
# D09  18  13   8   3  10  17  12   6   0   1
# D10  18  14  NA  NA  NA  NA  NA  NA  NA  NA
# D11  18  19  20  21  13   7   8  14   2   1
# D12  13  15  16   9   8   7  14  20  19  18

Puis calcule la longueur maximale

b <- lapply(a, function(el) {length(el) <- n ; el})
res <- do.call("rbind", b)

Et modifie les longueurs de chaque élément dans la liste

n <- max(sapply(a, length))

Enfin, changez les noms

a <- list(
    c(13, 5, 9, 16, 1, 7, 3, 20),
    c(0, 1, 2, 7, 8, 14, 20),
    c(2, 4, 7, 9, 12, 14, 16),
    0:9,
    c(18, 19, 20, 21, 22, 23, 6, 7, 8, 9),
    c(0, 1, 7, 13, 19, 6, 12, 18, 2, 8),
    23:22,
    c(18, 13, 8),
    c(18, 13, 8, 3, 10, 17, 12, 6, 0, 1),
    c(18, 14),
    c(18, 19, 20, 21, 13, 7, 8, 14, 2, 1),
    c(13, 15, 16, 9, 8, 7, 14, 20, 19, 18)
  )


2 commentaires

Merci qui fonctionne après avoir modifié les index avec le code de @MrFlick. Cependant, j'ai toujours besoin d'un nombre particulier de colonnes, peu importe s'il y a des données dans les listes ou non. Savez-vous comment je peux étendre la matrice par d'autres colonnes avec des NA (par exemple, deux de plus)?


En changeant n ? n <- max (sapply (a, length)) + 2



2
votes

Convertissez chaque composant de la liste L en une série ts , liez-les ensemble, supprimez les noms désordonnés qu'il attribue et transposez. Cela donnera une matrice avec une ligne par composant et autant de colonnes que le composant le plus long.

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


0 commentaires