instalar - ggplot2 r install
¿Cómo puedo manejar R CMD para comprobar las notas de "no visible binding for global variable" cuando mi sintaxis ggplot2 es sensata? (4)
EDITAR: Hadley Wickham señala que me equivoqué. La comprobación R CMD arroja NOTAS, no Advertencias. Lamento mucho la confusión. Fue mi descuido.
La versión corta
R CMD check
arroja esta nota cada vez que uso la sintaxis sensible de creación de trama en ggplot2:
no visible binding for global variable [variable name]
Entiendo por qué R CMD lo hace, pero parece estar criminalizando una veta entera de sintaxis sensible. No estoy seguro de qué pasos tomar para que mi paquete pase el R CMD check
y me admitan en CRAN.
El fondo
Sascha Epskamp publicó anteriormente esencialmente el mismo problema . La diferencia, creo, es que la página de subset()
dice que está diseñada para uso interactivo .
En mi caso, el problema no está en el subset()
sino en una característica central de ggplot2
: el argumento data =
.
Un ejemplo de código que escribo que genera estas notas
Aquí hay una subfunción en mi paquete que agrega puntos a un diagrama:
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é el control de R CMD es correcto
El cheque es técnicamente correcto. x.values
y y.values
- No están definidos localmente en la función
JitteredResponsesByContrast()
- No están predefinidos en la forma
x.values <- [something]
ni globalmente ni en la persona que llama.
En cambio, son variables dentro de un marco de datos que se define antes y pasa a la función JitteredResponsesByContrast()
.
Por qué ggplot2 hace que sea difícil aplacar el control de R CMD
ggplot2 parece fomentar el uso de un argumento de data
. El argumento de 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é estoy contento con ninguno
La estrategia NULLing out
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 sirve para nada más allá de apaciguar el
R CMD check
. - no refleja la intención Aumenta la expectativa de que la llamada
aes()
verá nuestras variables ahora NULL (no lo hará), a la vez que oscurecerá el propósito real (haciendo que la comprobación de CMD R conozca las variables que aparentemente no conocería si estaban vinculadas) - Los problemas de 1 y 2 se multiplican porque cada vez que escribes una función que devuelve un elemento de trazado, debes agregar un enunciado NULLing confuso
La estrategia with ()
Puede usar with()
para indicar explícitamente que las variables en cuestión se pueden encontrar dentro de un entorno más amplio. En mi caso, el uso 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 esperaría. Si with()
realmente resolvía el problema de señalar al intérprete donde están las variables, entonces ni siquiera debería necesitar el argumento data =
. 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, de nuevo, creo que esta solución tiene fallas similares a la estrategia de NULLing:
- Todavía tengo que pasar por cada función del elemento de trazado y ajustar la lógica en una llamada
with()
- La llamada
with()
es engañosa. Todavía necesito proporcionar un argumento dedata =
; todo lo quewith()
está haciendo es apaciguar laR CMD check
.
Conclusión
De la forma en que lo veo, hay tres opciones que podría tomar:
- Presionar a CRAN para que ignore las notas argumentando que son "espurias" (de acuerdo con la política de CRAN ), y hazlo cada vez que presento un paquete
- Repara mi código con una de las dos estrategias indeseables (NULLing o
with()
bloques) - Repique fuerte y espere que el problema desaparezca
Ninguno de los tres me hace feliz, y me pregunto qué es lo que la gente sugiere que yo (y otros desarrolladores de paquetes que quieran aprovechar ggplot2) debería hacer. Gracias a todos por adelantado. Realmente aprecio que incluso hayas leído esto :-)
¿Has probado con aes_string
lugar de aes
? Esto debería funcionar, aunque no lo he intentado:
aes_string(x = ''x.values'', y = ''y.values'')
Esta pregunta se ha formulado y respondido hace un tiempo, pero solo para su información, desde la versión 2.1.0 hay otra forma de evitar las notas: aes_(x=~x.values,y=~y.values).
Si
getRversion() >= "3.1.0"
Puede agregar una llamada en el nivel superior del paquete:
utils::suppressForeignCheck(c("x.values", "y.values"))
de:
help("suppressForeignCheck")
Tienes dos soluciones:
Reescribe tu código para evitar una evaluación no estándar. Para ggplot2, esto significa usar
aes_string()
lugar deaes()
(como describe Harlan)Agregue una llamada a
globalVariables(c("x.values", "y.values"))
en algún lugar en el nivel superior de su paquete.
Debes esforzarte por 0 NOTAS en tu paquete cuando te envíes a CRAN, incluso si tienes que hacer algo ligeramente hacky. Esto hace la vida más fácil para CRAN, y más fácil para usted.
(Actualizado el 31-12-2012 para reflejar mis últimos pensamientos sobre esto)