2016-09-10 5 views
3

ich diese verschachtelte Liste bekam:Naming Elemente einer verschachtelten Liste von ihrem Index in R

dico <- list(list(list(c("dim.", "dimension", "dimensions", "mesures" 
), c("45 cm", "45", "45 CM", "0.45m")), list(c("tamano", "volumen", 
"dimension", "talla"), c("45 cm", "45", "0.45 M", "45 centimiento" 
)), list(c("measures", "dimension", "measurement"), c("45 cm", 
"0.45 m", "100 inches", "100 pouces"))), list(list(c("poids", 
"poid", "poids net"), c("100 grammes", "100 gr", "100")), list(
    c("peso", "carga", "peso especifico"), c("100 gramos", "100g", 
    "100", "100 g")), list(c("weight", "net wieght", "weight (grammes)" 
), c("100 grams", "100", "100 g"))), list(list(c("Batterie oui/non", 
"batterie", "présence batterie"), c("Oui", "batterie", "OUI" 
)), list(c("bateria", "bateria si or no", "bateria disponible" 
), c("si", "bateria furnindo", "1")), list(c("Battery available", 
"battery", "battery yes or no"), c("yes", "Y", "Battery given" 
)))) 

[[1]] 
[[1]][[1]] 
[[1]][[1]][[1]] 
[1] "dim."  "dimension" "dimensions" "mesures" 

[[1]][[1]][[2]] 
[1] "45 cm" "45" "45 CM" "0.45m" 

Was ich will, ist eine Liste mit der gleichen Struktur zu schaffen, sondern die ursprünglichen Werte zu haben, möchte ich haben eine Art „Index“ Namen wie: die Anzahl der Elemente

[[1]] 
[[1]][[1]] 
[[1]][[1]][[1]] 
[1] "1|1|1|1"  "1|1|1|2" "1|1|1|3" "1|1|1|4" 

[[1]][[1]][[2]] 
[1] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4" 

und so weiter ...

natürlich ist nicht konstant durch die verschiedenen verschachtelten Indizes. Weiß jemand, wie man das macht? Ich habe von Rappel gehört, aber ich konnte es nicht schaffen.

Antwort

3

Wir verwenden melt (von reshape2) die verschachtelten list zu einem data.frame mit den Indexspalten (‚L1‘, ‚L2‘, ‚L3‘) und der ‚Wert‘ Spalte zu konvertieren, wandeln es in data.table (setDT(...)), gruppiert nach ‚L1‘, ‚L2‘, L3 ‚‘, so erhalten wir die Reihenfolge der Reihen (1:.N), paste die Elemente der Reihen mit do.call zu einem einzigen vector, dann relist es zu einem list mit dem gleichen Struktur wie die von 'dico' durch Angabe der skeleton.

library(data.table) 
library(reshape2) 
dico2 <- relist(do.call(paste, c(setDT(melt(dico))[, 1:.N , 
      by = .(L1, L2, L3)], sep="|")), skeleton = dico) 
dico2 
#[[1]] 
#[[1]][[1]] 
#[[1]][[1]][[1]] 
#[1] "1|1|1|1" "1|1|1|2" "1|1|1|3" "1|1|1|4" 

#[[1]][[1]][[2]] 
#[1] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4" 

#... 

#[[3]][[3]] 
#[[3]][[3]][[1]] 
#[1] "3|3|1|1" "3|3|1|2" "3|3|1|3" 

#[[3]][[3]][[2]] 
#[1] "3|3|2|1" "3|3|2|2" "3|3|2|3" 
7

Versuchen Sie diese rekursive Funktion mit einem 2-Linien-Körper. Es nimmt keine feste Tiefe an und erlaubt unsymmetrische Listen. Keine Pakete werden verwendet.

Es akzeptiert ein Objekt L und eine Ebene. Wenn das Objekt keine Liste ist, haben wir ein Blatt und es gibt seine Ebenen zurück. Wenn das Objekt eine Liste ist, dann haben wir einen Knoten und es iteriert über seine Komponenten, wobei indexer bei jedem Durchlauf der Verkettung von lev, i und | für die i-te Komponentenebene aufgerufen wird.

indexer <- function(L, lev = character(0)) { 
    if (!is.list(L)) paste0(lev, seq_along(L)) 
    else Map(indexer, L, paste0(lev, seq_along(L), "|")) 
} 

Beispiel 1 Mit dico von der Frage

> str(indexer(dico)) 
List of 3 
$ :List of 3 
    ..$ :List of 2 
    .. ..$ : chr [1:4] "1|1|1|1" "1|1|1|2" "1|1|1|3" "1|1|1|4" 
    .. ..$ : chr [1:4] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4" 
    ..$ :List of 2 
    .. ..$ : chr [1:4] "1|2|1|1" "1|2|1|2" "1|2|1|3" "1|2|1|4" 
    .. ..$ : chr [1:4] "1|2|2|1" "1|2|2|2" "1|2|2|3" "1|2|2|4" 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "1|3|1|1" "1|3|1|2" "1|3|1|3" 
    .. ..$ : chr [1:4] "1|3|2|1" "1|3|2|2" "1|3|2|3" "1|3|2|4" 
$ :List of 3 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "2|1|1|1" "2|1|1|2" "2|1|1|3" 
    .. ..$ : chr [1:3] "2|1|2|1" "2|1|2|2" "2|1|2|3" 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "2|2|1|1" "2|2|1|2" "2|2|1|3" 
    .. ..$ : chr [1:4] "2|2|2|1" "2|2|2|2" "2|2|2|3" "2|2|2|4" 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "2|3|1|1" "2|3|1|2" "2|3|1|3" 
    .. ..$ : chr [1:3] "2|3|2|1" "2|3|2|2" "2|3|2|3" 
$ :List of 3 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "3|1|1|1" "3|1|1|2" "3|1|1|3" 
    .. ..$ : chr [1:3] "3|1|2|1" "3|1|2|2" "3|1|2|3" 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "3|2|1|1" "3|2|1|2" "3|2|1|3" 
    .. ..$ : chr [1:3] "3|2|2|1" "3|2|2|2" "3|2|2|3" 
    ..$ :List of 2 
    .. ..$ : chr [1:3] "3|3|1|1" "3|3|1|2" "3|3|1|3" 
    .. ..$ : chr [1:3] "3|3|2|1" "3|3|2|2" "3|3|2|3" 

Beispiel 2 Hier ist ein Beispiel für eine Liste mit einer unterschiedlichen Tiefe und Mangel an Ausgewogenheit:

L <- list(list(1:3, 5:7), 9:10) 

Geben:

> str(indexer(L)) 
List of 2 
$ :List of 2 
    ..$ : chr [1:3] "1|1|1" "1|1|2" "1|1|3" 
    ..$ : chr [1:3] "1|2|1" "1|2|2" "1|2|3" 
$ : chr [1:2] "2|1" "2|2" 
Verwandte Themen