2011-12-28 9 views
6

¿Qué tipo de objeto se pasa al myFunc como x? No parece ser una expresión, ni una función y str simplemente lo evalúa. Entiendo que puedo usar force() para evaluar. Me pregunto si hay alguna forma de reunir más información sobre x sin evaluarlo.R - Detectando expresiones

myFunc = function(x) 
{ 
    is.expression(x)  
    is.function(x) 
    str(x) 
} 
myFunc({ x = 5; print(x + 1) }) 
+1

¿Qué pasa con la clase no parece (x) – Benjamin

+0

hacerlo indicando que una expresión. tampoco lo hace type() ni mode() – SFun28

+0

Creo que podría confundirse entre expresiones (que son básicamente listas de llamadas no evaluadas) y los resultados de una expresión. 'x' en su función es 6. – hadley

Respuesta

6

puede utilizar match.call para la extracción de los argumentos:

myFunc <- function(x) { 
    x <- match.call()$x 
    print(class(x)) 
    print(typeof(x)) 
    print(mode(x)) 
    print(storage.mode(x)) 
    print(is.expression(x)) 
    print(is.call(x)) 
    if (is.call(x)) print(x[[1]]) 
} 
myFunc({x = 5; print("a")}) 
myFunc(expression(x)) 
x <- factor(1) 
myFunc(x) 
myFunc(1) 

Probablemente lo que necesito decir que { es una función de R, por lo {...} no es más que call.

Actualizado: ¿por qué no es xfunction mientras { es function:

f <- function(x) { 
    x <- match.call()$x 
    print(eval(x[[1]])) 
    print(is.function(eval(x[[1]]))) 
} 

f({1}) 
+0

¡gracias por armar esto! Si {es una función, entonces ¿por qué is.function (x) devuelve FALSE? ¿Hay alguna manera de cambiar el entorno de x? – SFun28

+0

porque x es 'call', no' function'. 'Call' consta de' function' y 'arguments'. Ver también update. – kohske

2

creo class que hacer el truco ... Ver docs.

EDIT: De acuerdo con la docs,

para {, el resultado de la última expresión evaluada

Lo que significa que la clase es la clase resultante de la evaluación, por lo que no apareciendo como una "expresión". Se pasa después de la evaluación.

+0

Hmmm,' class' devuelve 'numeric' que me hace pensar que en realidad evalúa la expresión antes de probarla ... – nico

+0

En realidad, incluso si intenta asignar esa expresión a una variable, la La expresión se ejecuta inmediatamente, y usted termina con una variable numérica que contiene 6 ... – nico

+0

Exactamente. La evaluación se realiza inmediatamente, antes de la asignación o pasando el resultado a una función. – Benjamin

1

Dason acaba de publicar una respuesta similar a esto en Talkstats.com para determinar si un objeto es una trama de datos o una lista (click here for a link to that post). Yo sólo lo extendió a una expresión que creo que se adapte a sus necesidades.

j.list <- function(list, by = NULL){ 
    print("list") 
    print(list) 
} 

j.data.frame <- function(df, ..., by = NULL){ 
    print("data frame") 
    print(df) 
} 


j.expression <- function(expression, by = NULL){ 
    print("expression") 
    print(expression) 
} 

j <- function(x, ...){ 
    UseMethod("j") 
} 

j(list(test = "this is a list")) 
j(data.frame(test = 1:10)) 
j(expression(1+ 0:9)) 
+0

j ({x = 5; print (x + 1)}) arroja el error "no se aplicó ningún método para 'j' al objeto de la clase" c ('doble', 'numérico') "pero la solución parecía inteligente =) – SFun28

+0

No era necesariamente para determinar si algo era un marco de datos o una lista; era para adaptar la llamada a función a si el argumento era un marco de datos o una lista ya que el póster quería poder ofrecer una funcionalidad similar para ambos casos pero quería que la función dijera si el objeto que se pasó fue una lista o marco de datos. Pero gracias por el saludo. – Dason