2015-04-22 16 views
5

Voglio scrivere una funzione che valuti un'espressione in un frame di dati, ma che lo faccia utilizzando espressioni che possono o non possono contenere user- oggetti definiti. Penso che la parola magica sia "valutazione non standard", ma non riesco ancora a capirlo.R: valutazione di un'espressione in un frame di dati con argomenti passati come oggetto

Un semplice esempio (ancora realistico per i miei scopi): Dire, voglio valutare una chiamata lm() per le variabili trovate in un frame di dati.

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

Una funzione che quindi può essere scritta come segue:

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

Tale che ottengo ciò che voglio utilizzare il seguente comando.

f(mydf, lm(y~x)) 

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

Nice. Tuttavia, ci sono casi in cui è più conveniente salvare l'equazione del modello in un oggetto prima di chiamare lm(). Sfortunatamente la funzione sopra non lo fa più.

fml <- y~x 

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

Qualcuno può spiegare perché la seconda chiamata non funziona? Come potrebbe essere alterata la funzione, in modo tale che entrambe le chiamate portino ai risultati desiderati? (desiderato = modello adattato)

Cheers!

risposta

4

Da ?lm, re data argomento:

Se non si trova nei dati, le variabili sono tratte da ambiente (formula)

Nel primo caso, la formula viene creata sul eval(expr, df, pf) chiamata, quindi l'ambiente della formula è un ambiente basato su df. Nel secondo caso, la formula viene creata nell'ambiente globale, motivo per cui non funziona.

Poiché le formule vengono con il proprio ambiente, possono essere difficili da gestire in NSE.

Si potrebbe provare:

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

ma che probabilmente non è l'ideale per voi. A meno che non si verifichi se alcuni nomi nel parametro acquisito si risolvono con le formule e si riassegnano i loro ambienti, si avranno dei problemi. Peggio ancora, non è nemmeno necessariamente ovvio che riassegnare l'ambiente sia la cosa giusta da fare. In molti casi, si desidera cercare nell'ambiente della formula.

C'è stata una discussione stretta relazione su questo tema su R Chat:

+0

credo di sapere quello che vuoi dire, anche se mi sarebbe frase un po 'diverso . Vediamo se capisco questo: il problema è che 'eval()' deve cercare l'oggetto 'fml' prima che' lm() 'possa essere valutato nel suo insieme.Poiché 'fml' non è disponibile nel frame di dati,' eval' ricorre a cercarlo in 'pf'. La formula si trova lì perché è stata creata lì, ma non è necessario vedere 'y' o' x'. – SimonG

+1

@SimonG Il problema non è 'eval'. Il problema è che 'lm' cerca le variabili nell'ambiente (formula)' indipendentemente dal frame in cui viene valutata la chiamata 'lm'. – BrodieG

Problemi correlati