2015-12-31 5 views
12

erwartete ich habe die folgende ListeDollar Operator als Funktionsargument für sapply funktioniert nicht wie

test_list=list(list(a=1,b=2),list(a=3,b=4)) 

und ich möchte a alle Elemente mit Listenelementnamen extrahieren.

Ich kann dies tun über

sapply(test_list,`[[`,"a") 

, die mir gibt das korrekte Ergebnis

#[1] 1 3 

Wenn ich das gleiche mit Rs Dollar Operator $ versuchen, erhalte ich NULL

sapply(test_list,`$`,"a") 
#[[1]] 
#NULL 
# 
#[[2]] 
#NULL 

Allerdings, wenn ich es auf ein einzelnes Element vonverwende, Sie sollen

`$`(test_list[[1]],"a") 
#[1] 1 

Bin ich etwas offensichtlich hier fehlt?

Antwort

6

Von dem, was ich feststellen konnte, ist es eine Kombination aus zwei Dingen.

Zuerst the second element of $ is matched but not evaluated so it cannot be a variable.

Zweitens, wenn Argumente an Funktionen übergeben werden, werden sie den entsprechenden Variablen im Funktionsaufruf zugewiesen. Bei Übergabe an wird "a" einer Variablen zugewiesen und funktioniert daher nicht mehr mit $. Wir können sehen, durch auftretende von

sapply("a", print) 
[1] "a" 
    a 
"a" 

läuft dies zu eigenartigen Ergebnissen wie diese

führen kann
sapply(test_list, function(x, a) {`$`(x, a)}) 
[1] 1 3 

Wo trotz a ist eine Variable es (die nicht einmal zugewiesen wurde) $ Einstimmungen der Namen der Elemente in der Liste.

+0

Sehr interessante Antwort! Es zeigt im Grunde, dass bereits 'x =" a ";" $ "(test_list [[1]], x);' ein falsches Ergebnis ergibt. – cryo111

+0

Ähnlich wie das, was Sie gesagt haben, "$" (test_list [[1]], a) ergibt "1", obwohl kein Objekt "a" definiert wurde. – cryo111

11

Auswertung vs. keine

[[ wertet ihr Argument während $ nicht. L[[a]] ruft die Komponente L ab, deren Name in der Variablen a enthalten ist. $ übergibt nur den Argumentnamen selbst als Zeichenkette, so dass L$a die "a" Komponente von L findet. a wird nicht als eine Variable betrachtet, die den Komponentennamen enthält - nur eine Zeichenkette.

Below L[[b]] gibt die Komponente des L genannt "a" da die Variable b den Wert "a" während L$b kehrt die componet von L"b" benannt hat, weil mit dieser Syntax b nicht als Variable angesehen wird, sondern als Zeichenkette betrachtet, die sich ist bestanden.

L <- list(a = 1, b = 2) 
b <- "a" 
L[[b]] # same as L[["a"]] since b holds a 
## [1] 1 
L$b # same as L[["b"]] since b is regarded as a character string to be passed 
## [1] 2 

sapply

Jetzt, da wir verstehen den entscheidenden Unterschied bewteen $ und [[sehen, was mit sich geht sapply dieses Beispiel. Wir haben jedes Element test_list in ein "foo" Objekt gemacht und definiert unsere eigenen $.foo und [[.foo Methoden, die einfach zeigen, was R über das name Argument an die Methode übergeben:

foo_list <- test_list 
class(foo_list[[1]]) <- class(foo_list[[2]]) <- "foo" 

"$.foo" <- "[[.foo" <- function(x, name) print(name) 

result <- sapply(foo_list, "$", "a") 
## "..." 
## "..." 

result2 <- sapply(foo_list, "[[", "a")  
## [1] "a" 
## [1] "a" 

Was im ersten Fall geschieht, ist, dass sapply ruft whatever$... und ... wird nicht ausgewertet, so würde es für eine Liste Komponente suchen, die buchstäblich "..." heißt und natürlich gibt es keine solche Komponente, so whatever$... ist NULL daher die NULL in der Ausgabe in der Frage gezeigt. Im zweiten Fall whatever[[[...]] ergibt sich somit whatever[["a"]] das beobachtete Ergebnis.

Verwandte Themen