2015-04-22 35 views
5

Chcę napisać funkcję, która ocenia wyrażenie w ramce danych, ale taką, która robi to za pomocą wyrażeń, które mogą lub nie mogą zawierać użytkownika określone obiekty. Myślę, że magiczne słowo to "niestandardowa ocena", ale nie mogę tego jeszcze rozgryźć.R: Ocena wyrażenia w ramce danych za pomocą argumentów przekazanych jako obiekt

Jeden prosty przykład (ale realistyczny dla moich celów): Powiedz, chcę przetestować wywołanie zmiennych znajdujących się w ramce danych lm().

mydf <- data.frame(x=1:10, y=1:10) 

Funkcja, która ma tak można zapisać następująco:

f <- function(df, expr){ 
    expr <- substitute(expr) 
    pf <- parent.frame() 
    eval(expr, df, pf) 
} 

taka, że ​​dostanę to, co chcę za pomocą następującego polecenia.

f(mydf, lm(y~x)) 

# Call: 
# lm(formula = y ~ x) 
# 
# Coefficients: 
# (Intercept)   x 
# 1.12e-15  1.00e+00 

Nice. Istnieją jednak przypadki, w których wygodniej jest zapisać równanie modelu w obiekcie przed wywołaniem lm(). Niestety powyższa funkcja już tego nie robi.

fml <- y~x 

f(mydf, lm(fml)) 
# Error in eval(expr, envir, enclos): object 'y' not found 

Czy ktoś może wyjaśnić, dlaczego drugie połączenie nie działa? W jaki sposób można zmienić funkcję, tak aby oba połączenia prowadziły do ​​pożądanych rezultatów? (pożądany = dopasowany model)

Pozdrawiam!

Odpowiedz

4

Od ?lm ponownie data argument:

Jeśli nie znaleźć w danych, zmienne są pobierane z otoczenia (wzór)

W pierwszym przypadku, formuła jest utworzony w eval(expr, df, pf) call, więc środowisko formuły jest środowiskiem opartym na df. W drugim przypadku formuła jest tworzona w środowisku globalnym, dlatego nie działa.

Ponieważ formuły mają swoje własne środowisko, mogą być trudne w obsłudze w NSE.

można spróbować:

with(mydf, 
    { 
    print(lm(y~x)) 
    fml <- y~x 
    print(lm(fml)) 
    } 
) 

ale to chyba nie jest idealny dla Ciebie. Brak sprawdzania, czy jakiekolwiek nazwy w przechwyconym parametrze nie są zgodne z formułami i ponowne przypisywanie ich środowiskom, napotkają problemy. Gorzej, nie jest nawet oczywiste, że ponowne przypisanie środowiska jest właściwą rzeczą. W wielu przypadkach chcesz wyglądać w środowisku formuły.

Było luźno związane dyskusja na ten temat na R Chat:

+0

Chyba wiem, co masz na myśli, choć chciałbym fraza to trochę inaczej . Pozwól mi zobaczyć, jeśli rozumiem to: Problem polega na tym, że 'eval()' musi szukać obiektu 'fml' zanim' lm() 'może być oceniany jako całość.Ponieważ 'fml' nie jest dostępny w ramce danych,' eval' szuka tego w 'pf'. Formuła znajduje się tam, ponieważ została tam utworzona, ale nie widać "y" ani "x". – SimonG

+1

@SimonG Problemem nie jest "eval". Problem polega na tym, że 'lm' szuka zmiennych w' środowisku (formule) 'niezależnie od tego, w jakiej ramce jest oceniane wywołanie' lm'. – BrodieG