Usted ha especificado "expresión" como la clase del segundo argumento en este ejemplo de método. El primer ejemplo se devuelve un error porque
NewVar=Petal.Width*Petal.Length
se interpreta como un argumento con nombre de MYFUN con valor
Petal.Width*Petal.Length
que no tienen la oportunidad de ser evaluados, debido newvar no es un argumento para este método o genérico.
En el segundo ejemplo, no estoy seguro de lo que está pasando con las llaves cerradas, ya que mi error es diferente del que se muestra:
error en myfun (iris, {: error en la evaluación de la argumento 'y' al seleccionar un método para la función 'myfun': Error: objeto 'Petal.Width' no encontrado
Sin embargo, no recibo ningún error y obtengo el iris data.frame como salida cuando forzo su expresión a ser un objeto de expresión:
myfun(iris, expression(NewVar=Petal.Width*Petal.Length))
Creo que esto solo responde parcialmente a su pregunta, porque devolver trivialmente el data.frame del iris no era lo que quería. La expresión no está siendo evaluada adecuadamente por transform(). Sospecho desea que la salida para que coincida exactamente la salida de la siguiente versión modificable:
transform(iris, NewVar=Petal.Width*Petal.Length)
Aquí es un ejemplo corto evaluación de la expresión usando eval
z <- expression(NewVar = Petal.Width*Petal.Length)
test <- eval(z, iris)
head(test, 2)
[1] 0,28 0,28
Aquí está una versión que funciona para añadir una columna variable a los datos.marco:
setGeneric('myfun',function(x,y)standardGeneric('myfun'))
setMethod('myfun',c('data.frame','expression'), function(x,y){
etext <- paste("transform(x, ", names(y), "=", as.character(y), ")", sep="")
eval(parse(text=etext))
})
## now try it.
test <- myfun(iris, expression(NewVar=Petal.Width*Petal.Length))
names(test)
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "especie" "newvar"
head(test)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewVar
1 5.1 3.5 1.4 0.2 setosa 0.28
2 4.9 3.0 1.4 0.2 setosa 0.28
Una vez más, esta implementación tiene esencialmente está codificado que una, y solo una, columna de variable se agregará a la entrada data.frame, aunque el nombre de esa columna de variable y la expresión son arbitrarios y se proporcionan como una expresión. Estoy seguro de que hay una respuesta mejor, más general, que evaluaría la expresión contenida en y como si fuera una llamada directa en la función transform(), pero por el momento estoy perplejo de qué utilizar como el "inverso" apropiado. "función a expresión().
siempre existe la norma ..., si es que en realidad no quiere despachar en Y:
setGeneric('myfun', function(x, ...) standardGeneric('myfun'))
setMethod('myfun', 'data.frame', function(x, ...){
transform(x, ...)
})
Y esto funciona muy bien. Pero su pregunta era acerca de despachar realmente en un objeto de expresión.
Lo siguiente no funciona, pero creo que se está acercando. Tal vez alguien pueda entrar y hacer algunos ajustes finales:
setGeneric('myfun', function(x, y) standardGeneric('myfun'))
setMethod('myfun',c('data.frame', 'expression'), function(x, y){
transform(x, eval(y, x, parent.frame()))
})
## try out the new method
z <- expression(NewVar = Petal.Width*Petal.Length)
test <- myfun(iris, z)
names(test)
[1] "Sepal.Length" "Sepal.Width" "" "Petal.Length Petal.Width" "Species"
En esencia, el elemento "NewVar =" de la expresión no se pasó a transform() cuando llamamos a myfun().
Después de mucho ensayo y error, descubrí una manera que funciona de verdad. En primer lugar convertir el objeto de expresión en una lista con as.list(), y luego construir la llamada que desea con el magnifico
do.call()
El ejemplo completo es el siguiente:
setGeneric('myfun', function(x, y) standardGeneric('myfun'))
setMethod('myfun',c('data.frame', 'expression'), function(x, y){
do.call("transform", c(list(x), as.list(y)))
})
# try out the new method
z <- expression(NewVar = Petal.Width*Petal.Length)
test <- myfun(iris, z)
names(test)
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
[6] "NewVar"
Y el nuevo El objeto "prueba" data.frame tiene la columna "NewVar" que queríamos.
Véase la página 399-402 de SDA, donde Chambers describe por qué se debe evaluar cualquier argumento probado por firmas. –
@DWin: ¿quieres compartir un enlace? sfDA suena desconocido para mí, y creo que no está hablando de la Administración Estatal de Alimentos y Medicamentos ... –
Lo siento. "Software para Análisis de Datos" por John Chambers. Como un punto adicional noté que sus valores de firma no estaban asociados con nombres de argumento, mientras que en los ejemplos ese es el formato. (Nota: aún no ha cambiado a 'transformar' en el cuerpo de la pregunta) –