2013-05-05 9 views
5

Devo creare un nome aggiuntivo per my_function (i, x) (dove i può essere un numero intero compreso tra 1 e 25). Mi piacerebbe farlo funzionare come questoNome funzione aggiuntivo ma con meno argomenti

  • my_function1 (x) Sames come my_function (1, x)
  • my_function2 (x) sames come my_function (2, x)
  • my_function3 (x) Sames come my_function (3, x)
  • ...
  • my_function25 (x) sames come my_function (25, x)

Un modo per farlo raggiungere questo obiettivo potrebbe essere:

my_function1 <- function (x) my_function(1, x) 
my_function2 <- function (x) my_function(2, x) 
my_function3 <- function (x) my_function(3, x) 
... 

Ma dal momento che ci sono 25 di questi sarebbe ragionevole farlo in un ciclo. Per questo ho provato:

for(i in 1:25){ 
    assign(paste("my_function",i,sep=""),function(x) my_function(i,x)) 
} 

ma non funziona in quanto i è passato per riferimento e alla fine il risultato è stato

  • my_function1 (x) Sames come my_function (25, x)
  • my_function2 (x) sames come my_function (25, x)
  • my_function3 (x) sames come my_function (25, x)
  • ...

Come posso passare "i" in base al valore? O forse c'è un altro modo ...

Perché dovrei voler fare questo? Sto migliorando qualcun altro pacchetto R in termini di efficienza ma allo stesso tempo ho bisogno che sia compatibile con la vecchia versione.

+0

Benvenuti a SO. Troverai risposte migliori se pubblichi un [esempio riproducibile] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) la prossima volta.O questa volta, dal momento che puoi modificare il tuo post :-) –

+0

@ AriB.Friedman Grazie :) La prossima volta mi ricorderò di scrivere un esempio riproducibile. Curry sembra molto pulito e funziona perfettamente, ma in questo caso preferirei utilizzare alcune funzioni R standard in quanto non voglio installare alcun pacchetto aggiuntivo. – LukaszJ

risposta

6

Questo è chiamato currying ed è una parte della programmazione funzionale.

library(functional) 

myf <- function(a,x) cat(a,x,"\n") 
myf1 <- Curry(myf, a=1) 
myf1(5) 
for(i in seq(25)) assign(paste0("myf",i), Curry(myf,a=i)) 
> myf15(5) 
15 5 

Credo che ci sia una domanda importante qui come per perché che ci si vuole fare questo. Questo sembra esattamente il tipo di argomento per cui non ci sono molte funzioni correlate.

+0

+1 Non sapevo di curry (ho ancora tanto da imparare!). Grazie. –

+0

@ SimonO101 C'è più di una strada per Dublino. Buon uso di 'bquote'. –

+0

Tuttavia, ciò che ho restituito sopra non è sintatticamente valido! Stavo solo copiando copia dalla domanda. –

2

Penso bquote aiuterà qui:

for(i in 1:2){ 
    assign(paste("my_function",i,sep=""), bquote(function(x) my_function(i = .(i) , x))) 
} 

>my_function2 
# function(x) my_function(i = 2L, x) 

Ma il punto si trova ancora - perché si vuole per fare questo?

+0

Bene, sto migliorando qualcun altro pacchetto R in termini di efficienza ma allo stesso tempo ho bisogno che sia compatibile con la vecchia versione. Grazie per la soluzione! – LukaszJ

4

Bene, è possibile ottenere lo stesso risultato, utilizzando anche le funzioni base.

Il trucco è quello di forzare (force) la valutazione di i ad ogni iterazione e assegnare la funzione nella .Globalenv (o l'ambiente che ti piace)

my_function <- function(a, b) a + b 


lapply(1:10, function(i) { 
    force(i) 
    assign(paste0("my_function", i), function(x) my_function(i, x), envir = .GlobalEnv) 
} 
     ) 


my_function1(10) 
## [1] 11 

my_function9(10) 
## [1] 19 
+0

+1 bella soluzione. –

+0

@ SimonO101 grazie !!! Adoro la filosofia "c'è più di un modo per farlo" in R, non ero a conoscenza di 'Curry' e non pensavo a' bquote' in questo caso. ths – dickoa

+2

C'è più di un modo per farlo, ma c'è solo un modo per non farlo, e penso davvero che questo non dovrebbe essere fatto ... Scommetto che la prossima domanda dell'OP sarà "come faccio chiama 'my_function $ {i}()' per qualche valore di 'i'? – Spacedman

Problemi correlati