2015-04-14 42 views
5

Mam kilka małych funkcji, które generują losowe ciągi podobne do rnorm lub sample. Wszystkie te funkcje mają wspólne argumenty, dla uproszczenia załóżmy, że jednym z powszechnych argumentów jest n. Chciałbym utworzyć większą funkcję (funkcjonalną), która pobiera n jako i argument plus ..., która może być jedną z małych funkcji. Ta funkcja meta ocenia małe funkcje z zestawem n, jeśli mają ten argument. Oto przykład:Podaj wspólny brakujący argument w funkcjonowaniu

## LITTLE FUNKCJE

fun1 <- function(n, x = 1:10) sample(x, n, TRUE) 
fun2 <- function(n, x = LETTERS) sample(x, n, TRUE) 
fun3 <- function(n, x = 50) rnorm(n, x) 
fun4 <- function(n, x = 100, y = 10) rnorm(n, x, y) 

funkcjonalnej (META funkcja)

combiner <- function(n, ...){ 

## Where the magic needs to happen. Set n for `fun1` `fun2` and `fun4` 
## evaluate all these functions 

} 

## Here we pass `n = 6` 
combiner(
    6, 
    fun1(), 
    fun2, 
    rnorm(), 
    fun4(y=8) 
) 

Chciałbym to do oceny funkcji nawet jeśli są brakujące () tak jak w przypadku fun2 powyżej, ale jest to bardziej przyjemne. Myślę, że jest to możliwe, ponieważ mogą to zrobić rury rurowe magrittr.

## pożądany wynik

list(
    fun1(6), 
    fun2(6), 
    rnorm(6), 
    fun4(6, y=8) 
) 


## OUTPUT IS SEED DEPENDANT 
## [[1]] 
## [1] 2 1 6 6 1 1 
## 
## [[2]] 
## [1] "V" "Z" "A" "F" "F" "G" 
## 
## [[3]] 
## [1] -0.91932716 -0.05833169 1.75440750 2.19959565 -0.11145315 1.32216601 
## 
## [[4]] 
## [1] 107.48747 89.55798 93.15771 111.32380 100.82104 104.07829 

Odpowiedz

6

Oto jak bym podejść do tego:

combiner <- function(n, ...) { 
    ## Capture the unevaluated calls and symbols passed via ... 
    ll <- as.list(substitute(list(...)))[-1] 
    ## Process each one in turn 
    lapply(ll, FUN = function(X) { 
     ## Turn any symbols/names into calls 
     if(is.name(X)) X <- as.call(list(X)) 
     ## Add/replace an argument named n 
     X$n <- n 
     ## Evaluate the fixed up call 
     eval(X) 
    }) 
} 

combiner(6, fun1(), fun2, rnorm(), fun4(y=8)) 
# [[1]] 
# [1] 3 8 9 7 4 7 
# 
# [[2]] 
# [1] "Z" "M" "U" "A" "Z" "U" 
# 
# [[3]] 
# [1] 0.6100340 -1.0323017 -0.6895327 1.2534378 -0.3513120 0.3116020 
# 
# [[4]] 
# [1] 112.31979 91.96595 79.11932 108.30020 107.16828 89.46137 
+0

byłem brudząc każdy kędy ale nigdy nie zbliżył się do that.I've nigdy używane ' as.call' before. Dziękuję Ci. –