2013-08-13 11 views
7

Stavo passando attraverso some examples nella guida di hadley ai funzionali, e ho trovato un problema inaspettato.

Supponiamo che io sono un elenco di oggetti del modello,

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

e desidera estrarre qualcosa da ciascuno (come suggerito in questione di Hadley su una lista denominata "prove"). Mi aspettavo che uno di questi funzionasse:

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

Tuttavia, restituiscono valori nulli. Sembra che io non sto abusando della funzione $, come queste cose funzionano:

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

Comunque, sto solo facendo questo come un esercizio e sono curioso dove il mio errore è. So che potrei usare una funzione anonima, ma penso che ci debba essere un modo per usare la sintassi simile alla mia non-soluzione iniziale. Ho guardato attraverso i posti $ è menzionato in ?Extract, ma non ho visto alcuna spiegazione ovvia.

Ho appena realizzato che questo funziona:

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

e questo

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

Forse questo solo si riduce a qualche lapply voodoo che richiede funzioni anonime in cui dovrebbe essere necessario nessuno? Mi sembra di averlo sentito da qualche parte su SO prima.

+2

Nessun voodoo. La funzione "$" non valuta i suoi argomenti, mentre "[[" fa. –

+3

@DWin - puoi esporre per favore, non capisco cosa intendi con quello – eddi

+0

@Dwin Forse questo è proprio sopra la mia testa, ma non sono chiaro su cosa significhi qui la valutazione. Sembra valutare args bene quando chiamato direttamente, come in '\' $ \ '(bah [[1]], i = 'call')' ...? (argh: sfuggire ai backtick in linea è fastidioso) – Frank

risposta

4

Questo è documentato in ?lapply, nella "Nota" sezione (sottolineatura mia):

Per ragioni storiche, le chiamate create da lapply sono non valutata, e il codice è stato scritto (per esempio bquote) che si basa su questo. Questo significa che la chiamata registrata è sempre del modulo FUN(X[[0L]], ...), con 0L sostituito dall'indice intero corrente. Questo non è normalmente un problema, ma può essere se FUN utilizza sys.call o match.call o se è una funzione primitiva che fa uso della chiamata . Ciò significa che è spesso più sicuro chiamare le funzioni primitive con un wrapper, in modo che ad es. lapply(ll, function(x) is.numeric(x)) è richiesto in R 2.7.1 per garantire che la spedizione del metodo per is.numeric si verifichi correttamente.

+0

Sono ancora un po 'confuso - ciò che richiede la funzione '$' fa questo 'lapply (bah, \' $ \ ',' call ')' come risultato? Apparentemente non è '\' $ \ '(bah [[1L]], 'call')' che è come mi sembra di leggere quella nota (se si sostituisce '...' con ''call'' e' FUN 'con' \ '$ \' '). – eddi

+4

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

+0

@Peyton ahhh, vedo, grazie! – eddi

Problemi correlati