EDITAR: Hadley Wickham señala que hablo mal. R La comprobación CMD arroja NOTAS, no Advertencias. Lamento muchísimo la confusión. Fue mi descuido.
La versión corta
R CMD check
lanza esta nota cada vez que uso una sintaxis sensata de creación de gráficos en ggplot2:
no visible binding for global variable [variable name]
Entiendo por qué R CMD check hace eso, pero parece estar criminalizando toda una veta de sintaxis sensible. No estoy seguro de qué pasos tomar para que mi paquete pase R CMD check
y sea admitido en CRAN.
El fondo
Sascha Epskamp publicó anteriormente sobre esencialmente el mismo problema . La diferencia, creo, es que subset()
la página de manual dice que está diseñada para uso interactivo .
En mi caso, el problema no ha terminado subset()
sino una característica central de ggplot2
: el data =
argumento.
Un ejemplo de código que escribo que genera estas notas
Aquí hay una subfunción en mi paquete que agrega puntos a una gráfica:
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
, al analizar este código, dirá
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
¿Por qué la verificación R CMD es correcta?
La verificación es técnicamente correcta. x.values
yy.values
- No se definen localmente en la función
JitteredResponsesByContrast()
- No están predefinidos en la forma
x.values <- [something]
globalmente o en la persona que llama.
En cambio, son variables dentro de un marco de datos que se define anteriormente y se pasa a la función JitteredResponsesByContrast()
.
¿Por qué ggplot2 hace que sea difícil apaciguar la verificación R CMD?
ggplot2 parece alentar el uso de un data
argumento. El argumento de los datos, presumiblemente, es por qué este código se ejecutará
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
pero este código producirá un error de objeto no encontrado:
library(ggplot2)
hwy # a variable in the mpg dataset
Dos soluciones y por qué no estoy contento con ninguna
La estrategia de anulación
Matthew Dowle recomienda establecer primero las variables problemáticas en NULL, que en mi caso se vería así:
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))
)
)
}
Aprecio esta solución, pero no me gusta por tres razones.
- no tiene ningún propósito adicional más allá de apaciguar
R CMD check
. - No refleja la intención. Eleva la expectativa de que la
aes()
llamada verá nuestras variables ahora NULAS (no lo hará), mientras que oculta el propósito real (hacer que R CMD verifique las variables que aparentemente no sabría que están vinculadas) - Los problemas de 1 y 2 se multiplican porque cada vez que escribe una función que devuelve un elemento de trazado, debe agregar una declaración NULLing confusa
La estrategia con ()
Puede usar with()
para indicar explícitamente que las variables en cuestión se pueden encontrar dentro de un entorno más grande. En mi caso, el uso se with()
ve así:
JitteredResponsesByContrast <- function (data) {
with(data, {
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
}
)
}
Esta solución funciona Pero, no me gusta esta solución porque ni siquiera funciona de la manera que lo esperaría. Si with()
realmente resolviera el problema de señalar al intérprete a dónde están las variables, entonces ni siquiera debería necesitar el data =
argumento. Pero, with()
no funciona de esa manera:
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
Entonces, nuevamente, creo que esta solución tiene fallas similares a la estrategia NULLing:
- Todavía tengo que pasar por cada función de elemento de la trama y ajustar la lógica en una
with()
llamada - La
with()
llamada es engañosa. Todavía necesito proporcionar unadata =
discusión; todowith()
lo que hace es apaciguarR CMD check
.
Conclusión
A mi modo de ver, hay tres opciones que podría tomar:
- Presiona a CRAN para que ignore las notas argumentando que son "espurias" (de conformidad con la política de CRAN ), y hazlo cada vez que envíe un paquete
- Arreglar mi código con una de dos estrategias indeseables (NULLing o
with()
blocks) - Zumba muy fuerte y espero que el problema desaparezca
Ninguno de los tres me hace feliz, y me pregunto qué sugiere la gente que yo (y otros desarrolladores de paquetes que quieran aprovechar ggplot2) debería hacer. Gracias a todos de antemano. Realmente aprecio que hayas leído esto :-)
aes_string
transform
y subset
también (no es 100% seguro, pero que tiene sentido).