2013-08-13 9 views
7

Przeszedłem przez some examples w przewodniku hadleya do funkcjonałów i natknąłem się na nieoczekiwany problem.

Załóżmy, że mam listę obiektów modelu,

x=1:3;y=3:1; bah <- list(lm(x~y),lm(y~x)) 

i chcą, aby wyodrębnić coś od siebie (jak zasugerowano w Hadley pytanie o listę o nazwie „Badania”). Oczekiwano, że jeden z nich zadziała:

lapply(bah,`$`,i='call') # or... 
lapply(bah,`$`,call) 

Jednak te zwracają puste wartości. Wydaje się, że nie jestem nadużywania funkcji $, jak te rzeczy działają:

`$`(bah[[1]],i='call') 
`$`(bah[[1]],call) 

W każdym razie, ja po prostu robi to jako ćwiczenie i jestem ciekaw, gdzie moja pomyłka jest. Wiem, że mógłbym użyć anonimowej funkcji, ale myślę, że musi istnieć sposób użycia składni podobnej do mojego początkowego braku rozwiązania. Sprawdziłem miejsca $ wymienione w ?Extract, ale nie widziałem żadnego oczywistego wyjaśnienia.

Właśnie uświadomiłem sobie, że to działa:

lapply(bah,`[[`,i='call') 

i to

lapply(bah,function(x)`$`(x,call)) 

Może tego właśnie sprowadza się do jakiegoś lapply voodoo, który wymaga anonimowych funkcje gdzie powinny być potrzebne żadne? Czuję, że słyszałem to gdzieś na SO wcześniej.

+2

Brak voodoo. Funkcja "$" nie ocenia jej argumentów, podczas gdy "[[" robi. –

+3

@DWin - czy możesz wyjaśnić, nie rozumiem, co masz przez to na myśli? – eddi

+0

@Dwin Może to jest tuż nad moją głową, ale nie mam pojęcia, co oznacza tutaj ocena. Wydaje się oceniać argumenty w porządku, gdy są wywoływane bezpośrednio, tak jak w '\' $ \ '(bah [[1]], i = 'call')' ...? (argh: unikanie inline backticks jest denerwujące) – Frank

Odpowiedz

4

Jest to udokumentowane w ?lapply w „Note” sekcji (kopalni nacisk):

Ze względów historycznych, rozmowy tworzone przez lapply są unevaluated, i kod został napisany (np bquote), które polega na tym. Ten numer oznacza, że ​​zarejestrowane połączenie ma zawsze postać FUN(X[[0L]], ...), a 0L zastąpiono bieżącym indeksem całkowitym. To nie jest zwykle problemem, ale może być, jeśli FUN wykorzystuje sys.call lub match.call lub jeśli jest to prymitywny funkcja sprawia, że ​​korzystanie z połączenia . Oznacza to, że często bezpieczniej jest wywoływać funkcje pierwotne za pomocą opakowania, np. lapply(ll, function(x) is.numeric(x)) jest wymagane w R 2.7.1, aby upewnić się, że wysyłka metody dla is.numeric przebiega poprawnie.

+0

Nadal jestem nieco zdezorientowany - co wywołuje funkcja '$' 'lapply (bah, \' $ \ ', 'call')' wynikiem? To najwyraźniej nie '\' $ \ '(ba [[1L]], 'zadzwoń')', która jest, jak się wydaje się, że czytanie wiadomości (jeśli zastąpić '...' 'z 'i' FUN call'' 'z' \ '$ \' '). – eddi

+4

'\' $ \ '(bah [[1L]], ...)' – Peyton

+0

@Peyton ahhh, rozumiem, dzięki! – eddi