2015-12-31 6 views
12

mam Poniższa listaoperator Dolar jako argument funkcji dla sapply nie działa zgodnie z oczekiwaniami

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

i chcę, aby wyodrębnić wszystkie elementy z listy nazwy elementu a.

mogę to zrobić poprzez

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

który daje mi poprawny wynik

#[1] 1 3 

Gdy próbuję samo z Rs dolara operatora $, mam NULL

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

Jednak jeśli używam go na jednym elemencie z test_list działa zgodnie z oczekiwaniami

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

Czy brakuje tu czegoś oczywistego?

Odpowiedz

6

Z tego, co udało mi się ustalić, to połączenie dwóch rzeczy.

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

Po drugie, kiedy argumenty są przekazywane do funkcji, są przypisywane do odpowiednich zmiennych w wywołaniu funkcji. Po przejściu do sapply"a" jest przypisana do zmiennej i dlatego nie będzie już działać z $. Widzimy to przez występujące uruchamiając

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

Może to prowadzić do specyficznych wyników tak

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

gdzie mimo a będących zmiennymi (które nawet nie zostały przypisane) $ dopasowania go do nazwy elementów na liście.

+0

Bardzo interesująca odpowiedź! Zasadniczo pokazuje, że już 'x =" a ";" $ "(test_list [[1]], x);' daje niepoprawny wynik. – cryo111

+0

Również, podobnie jak powiedziałeś, '" $ "(test_list [[1]], a)' daje '1', chociaż nie zdefiniowano żadnego obiektu' a'. – cryo111

11

ocena vs. none

[[ ocenia swój argument natomiast $ nie. L[[a]] otrzymuje składnik L, którego nazwa jest przechowywana w zmiennej a. $ po prostu przekazuje nazwę argumentu jako ciąg znaków, dzięki czemu L$a znajdzie składnik "a" z L. a nie jest uważany za zmienną trzymającą nazwę komponentu - tylko ciąg znaków.

Poniżej L[[b]] zwraca składową L nazwie "a" ponieważ zmienna b ma wartość "a" mając na uwadze L$b przywraca CompoNet z L nazwie "b" bo z tej składni b nie jest traktowana jako zmienna, ale jest traktowany jako ciąg znaków, który sam jest przekazywane.

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

Teraz rozumiemy kluczową różnicę bewteen $ a [[aby zobaczyć, co się dzieje z sapply Rozważmy następujący przykład. Zrobiliśmy każdy element test_list w "foo" obiektu i zdefiniowane własne $.foo i [[.foo metod, które po prostu pokazać, co R przechodzi do sposobu poprzez name argumentu:

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" 

Co się dzieje w pierwszym przypadku jest to, że sapply dzwoni pod numer whatever$... i ..., więc nie szukałby składnika listy, który jest dosłownie nazwany "..." i, oczywiście, nie ma takiego komponentu, więc whatever$... jest NULL stąd NULLs pokazane na wyjściu w pytaniu. W drugim przypadku whatever[[[...]] ocenia się na whatever[["a"]], stąd obserwowany wynik.

Powiązane problemy