2014-10-27 14 views
5

Mi sono imbattuto in questo concetto un paio di volte, ma non conosco il nome e quindi non posso google per saperne di più. In sostanza, quando si guarda attraverso funzioni o anche semplici comandi altri hanno scritto, ho spesso vedere qualcosa di simile a questo:function (x) in R: scrivere una "funzione" senza definire una funzione?

apply(dataset, 1:2, function(x) 10 * x) 

In questo caso, sono stato in grado di capire che in qualche modo questa "funzione di falso" la funzione (x) moltiplicherebbe ogni elemento del set di dati per 10. Questa sembra una funzione utile, ma non sono ancora sicuro di quando o come lo si utilizza. È davvero una funzione? O funziona solo all'interno della famiglia di funzioni applicabili? Esiste un nome per questa cosa?

+4

Si chiama funzione anonima. Questo dovrebbe aiutare con Google. – joran

risposta

8

Questi sono chiamati "funzioni anonime" e sì, sono oggetti funzione reali, che semplicemente non sono stati assegnati a nessun simbolo prima di essere utilizzati.

Ecco il bit rilevante dal R language documentation:

Generalmente funzioni sono assegnate ai simboli, ma non hanno bisogno di essere. Il valore restituito dalla chiamata alla funzione è una funzione. Se a questo non viene assegnato un nome, si fa riferimento a una funzione anonima. Le funzioni anonime sono più frequentemente utilizzate come argomenti ad altre funzioni come la famiglia apply o quella esterna.

Anche se sono più tipicamente utilizzati in *apply() funzioni, essi non devono essere, come si può vedere qui, per esempio

(function(x,y){x*y + x/y})(2,5) 
# [1] 10.4 
6

Vuoi dire un (funzione anonima) lambda? Si potrebbe mettere qualcosa di simile nel tuo ~/.Rprofile del file:

`{` <- function(...) 
    base::`{`(
    if (length(sys.calls()) >= 4 && 
     identical(as.character(sys.call()[[1]]), "{") && 
     identical(as.character(sys.call(-4)[[1]]), "{")) 
     base::`{`(fn <- new('function'), 
     formals(fn) <- alist(x=), body(fn) <- sys.call(), fn) 
    else eval.parent(substitute(base::`{`(...))) 
) 

Poi si possono fare cose come:

sapply(1:10, {{x + 5}}) 
# [1] 6 7 8 9 10 11 12 13 14 15 

Questo è più vicino a linguaggi come Ruby o CoffeeScript che non hanno bisogno di invocare una parola chiave per fare un lambda (lì usano -> ma questo è già preso in R quindi ho usato doppie parentesi graffe). Mi sono appena inventato, quindi se ci sono bug fammelo sapere.

+2

Questo probabilmente non aiuta affatto l'OP ma è un'idea interessante. Io sono parecchio sovraccarico di '->'.] (Https://gist.github.com/klmr/25dc765211c59bb749b0) –

+0

Il mio problema è che la maggior parte delle persone con cui lavoro effettivamente usa '->' per l'assegnazione di un munging casuale in console - più facile che tornare all'inizio –

+0

Immagino che tu possa girare '%>%' in 'base :: \' <- \ ''? –

Problemi correlati