2017-03-18 2 views
2

zu tun haben, einen Blick auf diese "einfachen" Funktionen:Wie mit NSE und usemethod

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

test.default<-function(x,y,data){ 
    message("default") 
    print(deparse(substitute(x))) 
    print(deparse(substitute(y))) 
    print(deparse(substitute(data))) 
    print(match.call()) 
} 

test.formula <- function(x,...){ 
    message("formula") 
    print(deparse(substitute(x))) 
    print(match.call()) 
} 

Alles ist in Ordnung

data(iris) 
test.formula(Sepal.Length~Petal.Width,iris) 
test.default(Sepal.Length,Petal.Width,iris) 
test(Sepal.Length~Petal.Width,iris) 

Außer diesem:

test(Sepal.Length,Petal.Width,iris) 

Wegen NSE: object 'Sepal.Length' not found

Irgendeine Idee?

+0

interessiert sein Ich bin nicht ein Fehler und die dritte „Test“ immer wieder die gleiche wie die erste. Ich würde nicht erwarten, dass R in der Lage ist, einen Spaltennamen zu finden, es sei denn, Ihre Funktion liefert das Objekt 'iris' als Umgebung. –

+0

@ 42- versuchen Sie dieses: 'test (Kelchblatt, Blütenblatt, Iris)'? –

+0

Ja, aber 'Sepal.Length' ist kein R-Name im Suchpfad. Es ist ein Attribut von 'Iris' mit einem Zeichenwert. –

Antwort

0

ich eine Lösung gefunden, aber eine schwierige Sache ...

tryCatch.W.E <- function(expr) 
    { 
     W <- NULL 
     w.handler <- function(w){ # warning handler 
     W <<- w 
     invokeRestart("muffleWarning") 
      } 
     list(value = withCallingHandlers(tryCatch(expr, error = function(e) e), 
                   warning = w.handler), 
        warning = W) 
    } 

test <- function(x, ...) { 

    if (inherits(tryCatch.W.E(x)$value,"error")) { 

    return(test.default(x,...)) 
    } 

    UseMethod("test", x) 
} 

test.default <- function(x, y, data) { 
    message("default") 
    print(deparse(substitute(x))) 
    print(deparse(substitute(y))) 
    print(deparse(substitute(data))) 
    print(match.call()) 
} 

test.formula <- function(x, ...) { 
    message("formula") 
    print(deparse(substitute(x))) 
    print(match.call()) 
} 
test.formula(Sepal.Length ~ Petal.Width, iris) 
test.default(Sepal.Length, Petal.Width, iris) 
test(Sepal.Length ~ Petal.Width, iris) 

Nun ist dies ok:

require(ggplot2) 

test <- aes 
test(Sepal.Length, Petal.Width, iris) 
#  
* x -> Sepal.Length 
* y -> Petal.Width 
* -> iris 

:

test(Sepal.Length, Petal.Width, iris) 
0

ich mit zufrieden mehr sein würde Das Problem bei der Verwendung von S3-Versand ist, dass es für eine "nackte" Sepal.Length keinen Wert und somit keine Klasse gibt. Die aes Funktion verwendet nicht S3-Versand, sondern geht sofort zu match.call()[-1].

1

Es ist nicht einfach, nicht mit einer Lösung zu kommen, weil Sie nicht Ihr Endspiel hier angegeben haben, aber ich denke, ich stimme mit 42- überein, dass S3-Versand nicht das Werkzeug sein könnte. Sie könnten der Suche nach lazyeval::lazy_dots

library("lazyeval") 
tezt <- function(data, ...){ 
    dots <- lazyeval::lazy_dots(...) 
    dots 
} 

Sie geben Ihre ... zu lazy_dots und dann können Sie damit umgehen.

str(tezt(iris, Sepal.Length, Petal.Width)) 
#> List of 2 
#> $ :List of 2 
#> ..$ expr: symbol Sepal.Length 
#> ..$ env :<environment: 0x7fedb11bb720> 
#> ..- attr(*, "class")= chr "lazy" 
#> $ :List of 2 
#> ..$ expr: symbol Petal.Width 
#> ..$ env :<environment: 0x7fedb11bb720> 
#> ..- attr(*, "class")= chr "lazy" 
#> - attr(*, "class")= chr "lazy_dots" 

oder:

str(tezt(iris, Sepal.Length ~ Petal.Width)) 
#> List of 1 
#> $ :List of 2 
#> ..$ expr: language Sepal.Length ~ Petal.Width 
#> ..$ env :<environment: 0x7fedb11bb720> 
#> ..- attr(*, "class")= chr "lazy" 
#> - attr(*, "class")= chr "lazy_dots" 

Auch könnte man in hadley/rlang

Verwandte Themen