instalar - problema ggplot scale_y_log10()
plot in r ggplot (1)
Me he encontrado con un problema interesante con la escala utilizando ggplot. Tengo un conjunto de datos que puedo graficar bien usando la escala lineal predeterminada, pero cuando uso scale_y_log10 () los números desaparecen. Aquí hay un código de ejemplo y dos imágenes. Tenga en cuenta que el valor máximo en la escala lineal es ~ 700, mientras que la escala del registro da como resultado un valor de 10 ^ 8. Le muestro que todo el conjunto de datos tiene solo ~ 8000 entradas, por lo que algo no está bien.
Me imagino que el problema tiene algo que ver con la estructura de mi conjunto de datos y el agrupamiento, ya que no puedo replicar este error en un conjunto de datos común como "diamantes". Sin embargo, no estoy seguro de la mejor manera de solucionar problemas.
gracias zach cp
Edición: bdamarest puede reproducir el problema de escala en el conjunto de datos de diamante de esta manera:
example_1 = ggplot(diamonds, aes(x=clarity, fill=cut)) +
geom_bar() + scale_y_log10(); print(example_1)
#data.melt is the name of my dataset
> ggplot(data.melt, aes(name, fill= Library)) + geom_bar()
> ggplot(data.melt, aes(name, fill= Library)) + geom_bar() + scale_y_log10()
> length(data.melt$name)
[1] 8003
Aquí hay algunos datos de ejemplo ... y creo que veo el problema. El conjunto de datos fundido original puede tener ~ 10 ^ 8 filas de largo. Tal vez los números de fila se están utilizando para las estadísticas?
> head(data.melt)
Library name group
221938 AB Arthrofactin glycopeptide
235087 AB Putisolvin cyclic peptide
235090 AB Putisolvin cyclic peptide
222125 AB Arthrofactin glycopeptide
311468 AB Triostin cyclic depsipeptide
92249 AB CDA lipopeptide
> dput(head(test2))
structure(list(Library = c("AB", "AB", "AB", "AB", "AB", "AB"
), name = c("Arthrofactin", "Putisolvin", "Putisolvin", "Arthrofactin",
"Triostin", "CDA"), group = c("glycopeptide", "cyclic peptide",
"cyclic peptide", "glycopeptide", "cyclic depsipeptide", "lipopeptide"
)), .Names = c("Library", "name", "group"), row.names = c(221938L,
235087L, 235090L, 222125L, 311468L, 92249L), class = "data.frame")
ACTUALIZAR:
Los números de fila no son el problema. Aquí están los mismos datos graficados usando el mismo eje x de aes y el color de relleno y la escala es completamente correcta:
> ggplot(data.melt, aes(name, fill= name)) + geom_bar()
> ggplot(data.melt, aes(name, fill= name)) + geom_bar() + scale_y_log10()
> length(data.melt$name)
[1] 8003
geom_bar
y scale_y_log10
(o cualquier escala logarítmica) no funcionan bien juntos y no dan los resultados esperados.
El primer problema fundamental es que las barras van a 0, y en una escala logarítmica, 0 se transforma en infinito negativo (lo que es difícil de trazar). La cuna alrededor de esto generalmente comienza con 1 en lugar de 0 (ya que $ / log (1) = 0 $), no traza nada si hubo 0 conteos, y no te preocupes por la distorsión porque si se necesita una escala de registro probablemente no No te preocupes por estar fuera por 1 (no necesariamente cierto, pero ...)
Estoy usando el ejemplo de diamonds
que mostró @dbemarest.
Hacer esto en general es transformar la coordenada, no la escala (más adelante en la diferencia).
ggplot(diamonds, aes(x=clarity, fill=cut)) +
geom_bar() +
coord_trans(ytrans="log10")
Pero esto da un error.
Error in if (length(from) == 1 || abs(from[1] - from[2]) < 1e-06) return(mean(to)) :
missing value where TRUE/FALSE needed
que surge del problema del infinito negativo.
Cuando se usa una transformación de escala, la transformación se aplica a los datos, luego se hacen estadísticas y arreglos, luego las escalas se etiquetan en la transformación inversa (aproximadamente). Puedes ver lo que está sucediendo al hacer los cálculos tú mismo.
DF <- ddply(diamonds, .(clarity, cut), summarise, n=length(clarity))
DF$log10n <- log10(DF$n)
lo que da
> head(DF)
clarity cut n log10n
1 I1 Fair 210 2.322219
2 I1 Good 96 1.982271
3 I1 Very Good 84 1.924279
4 I1 Premium 205 2.311754
5 I1 Ideal 146 2.164353
6 SI2 Fair 466 2.668386
Si trazamos esto de la manera normal, obtendremos el gráfico de barras esperado:
ggplot(DF, aes(x=clarity, y=n, fill=cut)) +
geom_bar(stat="identity")
y escalar el eje y da el mismo problema que usar los datos no resumidos previamente.
ggplot(DF, aes(x=clarity, y=n, fill=cut)) +
geom_bar(stat="identity") +
scale_y_log10()
Podemos ver cómo ocurre el problema al trazar los valores log10()
de los conteos.
ggplot(DF, aes(x=clarity, y=log10n, fill=cut)) +
geom_bar(stat="identity")
Esto se parece al de scale_y_log10
, pero las etiquetas son 0, 5, 10, ... en lugar de 10 ^ 0, 10 ^ 5, 10 ^ 10, ...
Por lo tanto, el uso de scale_y_log10
hace los recuentos, los convierte en registros, apila esos registros y luego muestra la escala en el formulario anti-registro. Sin embargo, apilar los registros no es una transformación lineal, por lo que lo que le pidieron que haga no tiene ningún sentido.
La conclusión es que los gráficos de barras apiladas en una escala de registro no tienen mucho sentido porque no pueden comenzar en 0 (donde debería estar la parte inferior de una barra), y comparar partes de la barra no es razonable porque su tamaño depende en donde están en la pila. Considerado en cambio algo como:
ggplot(diamonds, aes(x=clarity, y=..count.., colour=cut)) +
geom_point(stat="bin") +
scale_y_log10()
O si realmente quieres un total para los grupos que normalmente te darían apilar las barras, puedes hacer algo como:
ggplot(diamonds, aes(x=clarity, y=..count..)) +
geom_point(aes(colour=cut), stat="bin") +
geom_point(stat="bin", colour="black") +
scale_y_log10()