2015-04-13 8 views
9

Ich habe ein Problem mit der Anwendungsfunktion übergeben Argumente an eine Funktion übergeben, wenn nicht benötigt. Ich verstehe, dass Sie nicht wissen, was Sie mit den optionalen Argumenten machen sollen und übergeben Sie sie einfach an die Funktion.Übergeben Sie nicht alle optionalen Argumente in anwenden

Aber trotzdem, hier ist das, was würde ich tun:

Zuerst habe ich eine Liste von Funktionen angeben möchten, die ich nutzen möchte.

Dann möchte ich eine Funktion erstellen, die diese angegebenen Funktionen auf einen Datensatz anwenden.

myFunc <- function(data, functions) { 
    for (i in 1:length(functions)) print(apply(X=data, MARGIN=2, FUN=functions[[i]])) 
} 

Das funktioniert gut.

data <- cbind(rnorm(100), rnorm(100)) 
myFunc(data, functions) 

[1] 100 100 
[1] -0.5758939 -5.1311173 

Aber ich möchte auch zusätzliche Argumente für einige Funktionen, z.

Die funktionieren nicht wie ich will. Wenn ich ändern myFunc zu:

myFunc <- function(data, functions, ...) { 
    for (i in 1:length(functions)) print(apply(X=data, MARGIN=2, FUN=functions[[i]], ...)) 
} 

functions als

functions <- list(length, sum, power) 

und dann meine Funktion versuche ich bekommen

myFunc(data, functions, p=2) 

Error in FUN(newX[, i], ...) : 
    2 arguments passed to 'length' which requires 1 

Wie kann ich dieses Problem lösen?

Sorry für die Wand des Textes. Vielen Dank!

Antwort

4

können Sie Curry von functional verwenden Sie den gewünschten Parameter zu fixieren, um die Funktion in der Liste der Funktion setzen Sie und schließlich durchlaufen diese Liste von Funktionen anwenden möchten:

library(functional) 

power <- function(x, p) x^p 
funcs = list(length, sum, Curry(power, p=2), Curry(power, p=3)) 
lapply(funcs, function(f) apply(data, 2 , f)) 

mit Ihrem Code können Sie Verwendung:

functions <- list(length, sum, Curry(power, p=2)) 
myFunc(data, functions) 
0

Eine Option besteht darin, die Parameter in einer Liste mit den Argumenten zu übergeben, die für jede Funktion benötigt werden. Sie können diese Parameter zu den anderen hinzufügen, die für apply benötigt werden, indem Sie c verwenden und dann do.call verwenden, um die Funktion aufzurufen. Etwas wie das. Ich wickle auch hier alle Ausgaben in eine Liste ein, anstatt print zu verwenden; Ihre Verwendung kann variieren.

power <- function(x, p) x^p 
myFunc <- function(data, functions, parameters) { 
    lapply(seq_along(functions), function(i) { 
     p0 <- list(X=data, MARGIN=2, FUN=functions[[i]]) 
     do.call(apply, c(p0, parameters[[i]])) 
    }) 
} 

d <- matrix(1:6, nrow=2) 
functions <- list(length, sum, power) 
parameters <- list(NULL, NULL, p=3) 
myFunc(d, functions, parameters) 
0

können Sie lazyeval Paket verwenden:

library(lazyeval) 


my_evaluate <- function(data, expressions, ...) { 
    lapply(expressions, function(e) { 
    apply(data, MARGIN=2, FUN=function(x) { 
     lazy_eval(e, c(list(x=x), list(...))) 
    }) 
    }) 
} 

Und es wie folgt verwenden:

my_expressions <- lazy_dots(sum = sum(x), sumpow = sum(x^p), length_k = length(x)*k) 
data <- cbind(rnorm(100), rnorm(100)) 
my_evaluate(data, my_expressions, p = 2, k = 2) 
1

Ich würde befürworten Oberst mit Curry Ansatz, aber wenn Sie auf Basis haften möchten R Sie können immer:

funcs <- list(length, sum, function(x) power(x, 2)) 

was ungefähr ist, was Curry endet

Verwandte Themen