2017-12-02 4 views
1

Sagen, ich habe 2 (oder mehr) Vektoren:erstellen verschachtelte Liste von 2 oder mehr Vektoren in R?

v1 <- letters[1:2] 
v2 <- letters[24:26] 

> v1 
[1] "a" "b" 

> v2 
[1] "x" "y" "z" 

Wie könnte ich eine verschachtelte Liste wie diese programmatisch konstruieren, die Listen von allen Kombinationen meiner Eingangsvektoren enthält? Edit: Ich möchte das ohne ineffiziente Looping-Strukturen machen.

> l1 <- list(list(v1[1], v2[1]), list(v1[1], v2[2]), 
     list(v1[1], v2[3]), list(v1[2], v2[1]), 
     list(v1[2], v2[2]), list(v1[2], v2[3])) 

> str(l1) 
List of 6 
$ :List of 2 
..$ : chr "a" 
..$ : chr "x" 
$ :List of 2 
..$ : chr "a" 
..$ : chr "y" 
$ :List of 2 
..$ : chr "a" 
..$ : chr "z" 
$ :List of 2 
..$ : chr "b" 
..$ : chr "x" 
$ :List of 2 
..$ : chr "b" 
..$ : chr "y" 
$ :List of 2 
..$ : chr "b" 
..$ : chr "z" 
+0

Gibt es einen bestimmten Grund, warum Sie dies in einer Liste im Gegensatz zu einem Datenrahmen benötigen? –

+0

Ja, möchte ich in Verbindung mit do.call verwenden: lapply (my_nested_list, do.call, what = my_function). – FB001

+0

Können Sie das klären? Gibt es eine Eigenschaft der Funktion, die verhindert, dass sie mit einem Datenrahmen verwendet wird? –

Antwort

1

Ein einfacher Weg ist Schleifen zu verwenden:

l1 <- list() 
list_pos <- 1L 

for (i in 1:length(v1)) { 
    for (j in 1:length(v2)) { 
    l1[[list_pos]] <- list(v1[i], v2[j]) 
    list_pos <- list_pos + 1L 
    } 
} 

bearbeiten:

Ich denke, Schleifen ein bisschen unfair, rep bekommen, aber hier ist etwas (hässlich) Code, sie vermeidet :

l2 <- apply(expand.grid(v1, v2), 1, as.list) 

Btw. Die Schleife ist viel schneller. Ich vermute, es gibt noch viel schönere und kreativere Möglichkeiten, dies noch zu tun.

+0

Richtig, ich habe vergessen zu erwähnen, dass ich Schleifen vermeiden möchte, aus keinem anderen Grund als zu lernen, wie man besseren Code schreibt. – FB001

+0

Danke - das erzeugt die Struktur, nach der ich suche. Ich werde meine Annahmen über Schleifen noch einmal überprüfen. Nicht sicher, aber ich denke, dass die Schleifenleistung bei längeren Vektoren oder einer erhöhten Anzahl von Vektoren schlecht skalieren würde. – FB001

+0

Ich denke, es skaliert schlecht, aber die Funktionen anwenden sind auch versteckte Schleifen. – snoram

1

Hier ist eine Lösung, die die erforderlichen Kombinationen in einen Datenrahmen generiert.

> v1 <- letters[1:2] 
> v2 <- letters[24:26] 
> 
> aResult <- expand.grid(v2,v1) 
> View(aResult) 
> aResult 
    Var1 Var2 
1 x a 
2 y a 
3 z a 
4 x b 
5 y b 
6 z b 
> 

Wenn der Datenrahmen in eine list() einer Kombination pro Listeneintrag aufgeteilt werden müssen, können wir dies mit split() erreichen.

#If the data frame must be split into a list, one entry per row 
aResult$id <- as.factor(1:nrow(aResult)) 
theList <- split(aResult,aResult$id) 

Drucken das erste Element in der Liste, sehen wir Folgendes.

> theList[[1]] 
    Var1 Var2 id 
1 x a 1 
> 
Verwandte Themen