EDIT: Hadley Wickham sottolinea che ho sbagliato a parlare. R Il controllo CMD sta generando NOTE, non Avvertenze. Mi dispiace terribilmente per la confusione. È stata la mia svista.
La versione corta
R CMD check
genera questa nota ogni volta che utilizzo una sintassi di creazione di grafici sensata in ggplot2:
no visible binding for global variable [variable name]
Capisco il motivo per cui il controllo R CMD lo fa, ma sembra criminalizzare un'intera vena di sintassi altrimenti sensata. Non sono sicuro di quali passi adottare per far passare il mio pacchetto R CMD check
e essere ammesso al CRAN.
Lo sfondo
Sascha Epskamp in precedenza aveva pubblicato essenzialmente lo stesso problema . La differenza, penso, è che subset()
la manpage dice che è progettata per un uso interattivo .
Nel mio caso, il problema non è risolto subset()
ma riguarda una caratteristica fondamentale di ggplot2
: l' data =
argomento.
Un esempio di codice che scrivo che genera queste note
Ecco una sotto-funzione nel mio pacchetto che aggiunge punti a un grafico:
JitteredResponsesByContrast <- function (data) {
return(
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
)
}
R CMD check
, analizzando questo codice, dirà
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
Perché il controllo R CMD è corretto
Il controllo è tecnicamente corretto. x.values
ey.values
- Non sono definiti localmente nella funzione
JitteredResponsesByContrast()
- Non sono predefiniti nel modulo
x.values <- [something]
né a livello globale né nel chiamante.
Al contrario, sono variabili all'interno di un frame di dati che viene definito in precedenza e passato alla funzione JitteredResponsesByContrast()
.
Perché ggplot2 rende difficile placare il controllo R CMD
ggplot2 sembra incoraggiare l'uso di un data
argomento. L'argomento dei dati, presumibilmente, è il motivo per cui questo codice verrà eseguito
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
ma questo codice produrrà un errore oggetto non trovato:
library(ggplot2)
hwy # a variable in the mpg dataset
Due soluzioni alternative e perché non sono contento di nessuno dei due
La strategia di NULLing out
Matthew Dowle consiglia di impostare prima le variabili problematiche su NULL, che nel mio caso sarebbe simile al seguente:
JitteredResponsesByContrast <- function (data) {
x.values <- y.values <- NULL # Setting the variables to NULL first
return(
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
)
}
Apprezzo questa soluzione, ma non mi piace per tre motivi.
- non ha alcuno scopo aggiuntivo oltre a placare
R CMD check
. - non riflette l'intento. Aumenta l'aspettativa che la
aes()
chiamata vedrà le nostre variabili ora-NULL (non lo farà), mentre oscura lo scopo reale (facendo in modo che R CMD verifichi le variabili che apparentemente non saprebbero altrimenti che erano legate) - I problemi di 1 e 2 si moltiplicano perché ogni volta che si scrive una funzione che restituisce un elemento grafico, è necessario aggiungere un'istruzione NULLing confusa
La strategia with ()
Puoi usare with()
per segnalare esplicitamente che le variabili in questione possono essere trovate all'interno di un ambiente più grande. Nel mio caso, l'utilizzo with()
è simile al seguente:
JitteredResponsesByContrast <- function (data) {
with(data, {
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
}
)
}
Questa soluzione funziona. Ma questa soluzione non mi piace perché non funziona nemmeno come mi aspetterei. Se with()
sono stati davvero risolvere il problema di indicare l'interprete al punto in cui le variabili sono, allora dovrei nemmeno bisogno della data =
discussione. Ma with()
non funziona in questo modo:
library(ggplot2)
p <- ggplot()
p <- p + with(mpg, geom_point(aes(x = hwy, y = cty)))
p # will generate an error saying `hwy` is not found
Quindi, ancora una volta, penso che questa soluzione abbia difetti simili alla strategia NULLing:
- Devo ancora passare attraverso ogni funzione dell'elemento trama e avvolgere la logica in una
with()
chiamata - La
with()
chiamata è fuorviante. Devo ancora fornire undata =
argomento; tuttowith()
ciò che sta facendo è appaganteR CMD check
.
Conclusione
A mio modo di vedere, ci sono tre opzioni che potrei prendere:
- Fai pressioni su CRAN per ignorare le note sostenendo che sono "spurie" (ai sensi della politica CRAN ) e fallo ogni volta che invio un pacchetto
- Correggi il mio codice con una delle due strategie indesiderate (NULLing o
with()
blocchi) - Ronza molto forte e spero che il problema scompaia
Nessuno dei tre mi rende felice, e mi chiedo cosa dovrebbe suggerire la gente (e altri sviluppatori di pacchetti che vogliono attingere a ggplot2). Grazie a tutti in anticipo. Apprezzo molto la tua lettura anche attraverso questo :-)
aes_string
transform
e subset
troppo (non sicuro al 100%, ma ha senso).