Penso che la risposta di @joran sia giusta ma forse posso provare a spiegare un modo diverso.
La "funzione" (
in R è essenzialmente la funzione di identità. Ripercorre ciò che hai passato. È quasi come se non fosse lì. Non c'è differenza tra ciò che verrà restituito da queste dichiarazioni
x #1
(x) #2
((x)) #3
La parentesi appena passthrough il valore all'interno. Puoi aggiungere tutte le parentesi che vuoi e non cambierà ciò che viene restituito. Il valutatore esamina ((x))
, vede la parentesi esterna e sa di restituire semplicemente il valore della cosa all'interno della parentesi. Quindi ora sta analizzando solo (x)
, e di nuovo, vede la parentesi esterna e restituirà semplicemente il valore all'interno della parentesi, che è x
. La parentesi passa solo attraverso il valore dall'interno; non lo valutano
Il valore nudo x
è un nome (o simbolo). Un nome non è legato unicamente a un valore. La mappatura tra nomi e valori varia in base all'ambiente. Ecco perché i nomi devono essere valutati in un particolare contesto per ottenere un valore.Considerare questi esempi
aa <- 5
dd <- data.frame(aa=20)
x <- as.name("aa")
foo <- function(x) {aa<-10; eval(x)}
eval(x)
# [1] 5
foo(x)
# [1] 10
eval(x, dd)
# [1] 20
Questo comportamento è in realtà altamente auspicabile. E 'ciò che rende le funzioni che richiedono il lavoro di valutazione non standard, come
subset(mtcars, hp<100)
Quando si utilizza la console di R, si comporta come una REPL - si legge l'input, lo valuta, lo stampa, e quindi attende l'input successivo. Si noti che fa solo un livello di valutazione e la valutazione avviene nell'ambiente "corrente". Non valuta in modo ricorsivo il valore restituito da un'espressione. Quindi, quando si fa
x <- as.name("aa")
x # identical to (x)
# aa
quando il REPL arriva alla fase di valutazione, valuta il nome x
che punta al nome aa
. Questo è tutto. Un livello di valutazione. Il nome aa
non viene successivamente valutato.
C'è una nota nella pagina ?eval
aiuto che dice questo:
eval valuta il suo primo argomento nell'ambito corrente prima di passarlo al valutatore
Non c'è un "doppio" la valutazione sta accadendo lì. Sta semplicemente valutando i suoi parametri proprio come qualsiasi altra funzione in R. Per esempi
aa <- 5
bar <- function(x) print(x)
bar(aa+2)
# [1] 7
Esso stampa "7", non "AA + 2" perché la funzione ha valutato che è il parametro prima della stampa. Si spiega anche le differenze tra questi due
dd <- data.frame(bb=20)
xx <- as.name("bb")
eval(bb, dd)
# Error in eval(bb, dd) : object 'bb' not found
eval(xx, dd)
# [1] 20
Nel primo eval()
chiamata, R è in grado di valutare bb
nel contesto attuale in modo da ottenere l'errore. Ma nota che
evalq(bb, dd)
funziona perché evalq
non cerca di valutare il primo parametro espressione.
Sono sconcertato dalla tua modifica. Sembra che tu stia chiedendo perché gli sviluppatori di R non hanno fatto "get' do cosa fa" eval', ma poi la risposta dovrebbe essere perché fanno due cose diverse: una valuta un'espressione (che può essere un simbolo) e l'altro recupera oggetti dove si specifica il nome (simbolo) dell'oggetto tramite un carattere. Perché non dovresti_ dividere funzionalità diverse in due diverse funzioni? – joran