2015-11-18 17 views
9

Ich habe eine Frage zu dem Bereich, in dem Funktionsnamen in data.table::dcast Aufrufen ausgewertet werden (data.table Version 1.9.6, R 3.2.2).Name der dynamischen/privaten Funktion in dcast.data.table

Ich möchte den Funktionsnamen machen, aber das schlägt fehl. Hier

ist, was ich habe versucht:

library(data.table) 
DT <- data.table(value = c(1:10), 
       cat1 = c("a", "b", "a", "b", "a", "b", "a", "b", "c", "a"), 
       cat2 = c("x", "x", "x", "y", "y", "y", "y", "y", "y", "x")) 

Dies funktioniert:

result1 <- dcast.data.table(DT, cat1 ~ cat2, value.var = "value", fun = sum) 

Jetzt mache ich meine eigene Funktion, die auch funktioniert:

f1 <- function(x) { 
    y <- sum(x)^2 
    return(y) 
} 
result2 <- dcast.data.table(DT, cat1 ~ cat2, value.var = "value", fun = f1) 

Here I do das gleiche, aber ich erstelle eine private Funktion innerhalb einer Funktion. Dies schlägt jedoch mit Error in eval(expr, envir, enclos) : could not find function "f2" fehl.

Wenn ich f2 durch f1 ersetze funktioniert es und ruft f1. Es sieht so aus, als würde man die globale Umgebung betrachten, um den Ausdruck fun = f2 auszuwerten, und f2 existiert nur im lokalen Bereich.

testFunction <- function(DT1) { 
    f2 <- function(x) { 
     y <- sum(x)^2 
     return(y) 
    } 
    r3 <- dcast.data.table(DT1,cat1 ~ cat2, value.var = "value", fun = f2) 
    return(r3) 
} 
result3 <- testFunction(DT) 

Gibt es einen Weg dahin? Was ich wirklich machen wollte, ist, den Funktionsnamen f2 dynamisch zu machen, so dass ich zum Beispiel "f3" übergebe und die private Funktion f3 aufruft.

Ich hätte gehofft, dass so etwas wie

functionName = "f3" 
r3 <- dcast.data.table(DT1, cat1 ~ cat2, value.var = "value", fun = get(functionName)) 

... mich dort bekommen würde, aber das scheint nicht zu funktionieren. Irgendwelche Ideen?

+3

Ich denke, das ist das gleiche wie [Bug # 1369] (https://github.com/Rdatatable/data.table/issues/1369) - noch nicht festgelegt ist. – Arun

+2

Schöne erste Frage mit einem klar beschriebenen Problem, Spielzeug Daten und Code, den Sie versucht haben. Willkommen bei SO! Und +1 natürlich. – Henrik

Antwort

3

Basierend auf dem Fehlerbericht konnte ich das Problem vorerst umgehen, indem ich einen Parameter namens "fun.aggregate" verwendete.

Danke, dass Sie mich darauf hingewiesen haben.

Der folgende Code funktioniert und erreicht, was ich brauche. Ich kann einen bereits vorhandenen Funktionsnamen wie Mittelwert oder eine lokal definierte Funktion übergeben.

testFunction <- function(DT1,functionName="mean") { 

    f2 <- function(x) { 
     y <- sum(x)^2 
     return(y) 
    } 

    fun.aggregate <- get(functionName) 

    r3 <- dcast.data.table(DT1,cat1~cat2,value.var="value",fun.aggregate=fun.aggregate) 
    return(r3) 
} 
result3 <- testFunction(DT,"mean") 
result4 <- testFunction(DT,"f2") 
Verwandte Themen