2011-12-28 8 views
5

Qualcuno potrebbe spiegare il seguente codice? Sto sostituendo la funzione di layout nel pacchetto grafica con la mia versione, ma sembra riapparire magicamenteSostituzione permanente di una funzione

env = environment(graphics:::layout) 
unlockBinding("layout" , env = env) 
assign("layout" , function(){} , envir = env) 
lockBinding("layout" , env = env) 

# this still shows the original layout function! how is that possible? 
layout 

# this shows function(){} as expected 
graphics:::layout 
+0

tutti - mi scuso per tutte le domande relative agli ambienti ultimamente. Questo sta dimostrando di essere un argomento complicato e confuso. Se ci sono materiali di lettura consigliati (diversi dai PDF R standard che non sono molto utili), per favore fatemelo sapere! – SFun28

+1

Non chiedere scusa; Ho imparato molto da loro me stesso. Non ce l'ho nemmeno io, ma ho sentito che le [Chambers] (http://www.amazon.com/Software-Data-Analysis-Programming-Statistics/dp/1441926127/ref=sr_1_9?s=books&ie = UTF8 & qid = 1325110851 & sr = 1-9) book è una sorta di bibbia di programmazione R (al contrario di calcolo statistico). – joran

+0

In realtà ho appena ordinato quel libro un'ora fa. =) non vedo l'ora di abbassarlo. Grazie per le parole di incoraggiamento, joran! – SFun28

risposta

6

Il problema è che si sta assegnando la nuova versione di layout alla grafica namespace, che è ciò che viene restituito da environment(graphics:::layout). Si invece di si desidera eseguire l'assegnazione nel pacchetto della grafica allegata (ovvero l'ambiente che appare come "package:graphics" nel percorso di ricerca).

Nel tuo esempio, quando alla ricerca di layout, R ricerche verso il basso l'elenco dei pacchetti collegati restituiti da search(), e trova l'originale layout in package:graphics, prima si arriva mai a funzionare avere assegnato in namespace:graphics.

La soluzione è semplice, richiede solo un cambiamento di ambiente assegnato env nella prima riga:

# Assign into <environment: package:graphics> 
# rather than <environment: namespace:graphics> 
env <- as.environment("package:graphics") 

unlockBinding("layout" , env = env) 
assign("layout" , function(){} , envir = env) 
lockBinding("layout" , env = env) 

# Now it works as expected 
layout 
# function(){} 

Un po 'più elaborazione, che può essere utile per alcuni:

search() # Shows the path along which symbols typed at the command 
      # will be searched for. The one named "package:graphics" 
      # is where 'layout' will be found. 

# None of these return the environment corresponding to "package graphics" 
environment(layout) 
environment(graphics::layout) 
environment(graphics:::layout) 

# This does 
as.environment("package:graphics") 
+0

grazie, Josh! Quindi perché 'env = environment (graphics ::: layout)' non funziona ma 'env <- as.environment (" pacchetto: graphics ")' fa? – SFun28

+1

Vedere anche 'assignInNamespace' - le cose si complicano ulteriormente se si vogliono cambiare i metodi S3. – hadley

+0

@ SFun28: Il primo ottiene l'ambiente dello spazio dei nomi che utilizza solo la grafica, mentre il secondo ti dà l'ambiente del pacchetto grafico che tutto il resto utilizza. (Non sono sicuro di come questo influirebbe sugli altri pacchetti allegati che importano la grafica) – hadley

Problemi correlati