2013-05-05 19 views
5

Potrzebuję utworzyć dodatkową nazwę dla funkcji my_function (i, x) (gdzie i może być liczbą całkowitą od 1 do 25). ja jak go do pracy jak toDodatkowa nazwa funkcji, ale z mniejszą liczbą argumentów.

  • my_function1 (X) SAMES jak My_function (1 x)
  • my_function2 (x) sames jak My_function (2 x)
  • my_function3 (x) sames jak My_function (3 x)
  • ...
  • my_function25 (x) sames jak My_function (25, x)

Jednym ze sposobów osiągnięcia tego celu byłoby:

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

Ale ponieważ jest ich 25, rozsądnie byłoby zrobić to w pętli. Do tego Próbowałem:

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

ale to nie działa, ponieważ i jest przekazywane przez referencję i w końcu wynik był

  • my_function1 (x) sames jak My_function (25, x)
  • my_function2 (x) sames jak My_function (25, x)
  • my_function3 (x) sames jak My_function (25, x)
  • ...

Jak przekazać "i" według wartości? A może jest jakiś inny sposób ...

Dlaczego miałbym to robić? Poprawiam niektóre z innych pakietów R pod kątem wydajności, ale jednocześnie potrzebuję ich zgodności ze starszą wersją.

+0

Zapraszamy do SO. Znajdziecie lepsze odpowiedzi, jeśli następnym razem opublikujecie [przykład odtwarzalny] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example).Lub tym razem, ponieważ możesz edytować swój wpis :-) –

+0

@ AriB.Friedman Dzięki :) Następnym razem będę pamiętać, aby napisać powtarzalny przykład. Curry wygląda bardzo czysto i działa idealnie, ale w tym przypadku wolałbym używać standardowych funkcji R, ponieważ nie chcę instalować żadnych dodatkowych pakietów. – LukaszJ

Odpowiedz

6

To się nazywa curry i jest częścią programowania funkcjonalnego.

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 

Chyba nie jest ważne pytanie tutaj, aby dlaczego że chcesz to zrobić. Wydaje się, że to dokładnie to, na co chcesz argumentować, a nie wiele powiązanych funkcji.

+0

+1 Nie wiedziałem o curry (wciąż mam tyle do nauczenia się!). Dzięki. –

+0

@ SimonO101 Jest więcej niż jedna droga do Dublina. Miłe użycie 'bquote'. –

+0

Jednak to, co wróciłem powyżej, nie jest poprawne pod względem składni! Właśnie kopiowałem wklejanie z pytania. –

2

myślę bquote pomoże tutaj:

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) 

Ale chodzi jeszcze stoi - dlaczego chcesz to zrobić?

+0

Cóż, poprawiam czyjś inny pakiet R pod względem wydajności, ale jednocześnie potrzebuję go do kompatybilności ze starszą wersją. Dzięki za rozwiązanie! – LukaszJ

4

Cóż, możesz osiągnąć ten sam rezultat, używając również funkcji base.

Sztuką jest, aby wymusić (force) ocenę i w każdej iteracji i przypisać funkcję w .Globalenv (lub środowiska chcesz)

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 fajne rozwiązanie. –

+0

@ SimonO101 thanks !!! Uwielbiam filozofię "jest więcej niż jeden sposób to zrobić" w R, również nie znałem 'Curry' i nie myślałem o" bquote "w tym przypadku. thks – dickoa

+2

Jest więcej niż jeden sposób, aby to zrobić, ale jest tylko jeden sposób, aby tego nie robić i naprawdę uważam, że to jest coś, czego nie powinno się robić ... Założę się, że następne pytanie z PO będzie brzmiało "jak to zrobić? wywołaj 'my_function $ {i}()' dla pewnej wartości 'i'? – Spacedman