studio - Use stat_summary para anotar la gráfica con el número de observaciones
ggplot2 r install (2)
¿Cómo puedo usar stat_summary
para etiquetar un diagrama con n = x
donde x
es una variable? Aquí hay un ejemplo del resultado deseado:
Puedo hacer la trama anterior con este código bastante ineficiente:
nlabels <- sapply(1:length(unique(mtcars$cyl)), function(i) as.vector(t(as.data.frame(table(mtcars$cyl))[,2][[i]])))
ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
geom_boxplot(fill = "grey80", colour = "#3366FF") +
geom_text(aes(x = 1, y = median(mtcars$mpg[mtcars$cyl==sort(unique(mtcars$cyl))[1]]), label = paste0("n = ",nlabels[[1]]) )) +
geom_text(aes(x = 2, y = median(mtcars$mpg[mtcars$cyl==sort(unique(mtcars$cyl))[2]]), label = paste0("n = ",nlabels[[2]]) )) +
geom_text(aes(x = 3, y = median(mtcars$mpg[mtcars$cyl==sort(unique(mtcars$cyl))[3]]), label = paste0("n = ",nlabels[[3]]) ))
Esta es una continuación de esta pregunta: ¿Cómo agregar un número de observaciones por grupo y usar la media del grupo en ggplot2 boxplot? donde puedo usar stat_summary
para calcular y mostrar el número de observaciones, pero no he podido encontrar una manera de incluir n =
en el resultado stat_summary
. Parece que stat_summary
podría ser la forma más eficiente de hacer este tipo de etiquetado, pero otros métodos son bienvenidos.
La mayoría de las cosas en R
están vectorizadas, por lo que puede aprovechar eso.
nlabels <- table(mtcars$cyl)
# To create the median labels, you can use by
meds <- c(by(mtcars$mpg, mtcars$cyl, median))
ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
geom_boxplot(fill = "grey80", colour = "#3366FF") +
geom_text(data = data.frame(), aes(x = names(meds) , y = meds,
label = paste("n =", nlabels)))
En cuanto a los nlables
:
En lugar de su declaración sapply
simplemente puede usar:
nlabels <- table(mtcars$cyl)
Tenga en cuenta que su código actual está tomando lo anterior, convirtiéndolo, transponiéndolo, y luego iterando sobre cada fila solo para tomar los valores uno por uno, luego vuelva a juntarlos en un solo vector.
Si realmente los quieres como un vector entero no dimensionado, usa c()
nlabels <- c(table(mtcars$cyl))
pero, por supuesto, incluso esto no es necesario para lograr lo anterior.
Puede hacer su propia función para usar dentro de stat_summary()
. Aquí n_fun
calcule el lugar del valor y como median()
y luego agregue label=
que consiste en n=
y el número de observaciones. Es importante usar data.frame()
lugar de c()
porque paste0()
producirá carácter pero el valor de y
será numérico, pero c()
hará ambos caracteres. Luego, en stat_summary()
use esta función y geom="text"
. Esto asegurará que para cada valor de x, la posición y la etiqueta solo se realicen a partir de los datos de este nivel.
n_fun <- function(x){
return(data.frame(y = median(x), label = paste0("n = ",length(x))))
}
ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
geom_boxplot(fill = "grey80", colour = "#3366FF") +
stat_summary(fun.data = n_fun, geom = "text")