Проблема ggplot scale_y_log10()

У меня возникла интересная проблема с масштабированием с помощью ggplot. У меня есть набор данных, который я могу нарисовать просто отлично, используя линейную шкалу по умолчанию, но когда я использую scale_y_log10(), числа уходят. Вот пример кода и две картинки. Обратите внимание, что максимальное значение в линейном масштабе составляет ~ 700, а масштаб масштабирования журнала - 10 ^ 8. Я покажу вам, что весь набор данных составляет всего ~ 8000 записей, поэтому что-то не так.

Я предполагаю, что проблема имеет какое-то отношение к структуре моего набора данных и биннинга, поскольку я не могу воспроизвести эту ошибку на общем наборе данных, например "бриллианты". Однако я не уверен, что лучший способ устранения неполадок.

спасибо, zach cp


Изменить: bdamarest может воспроизвести масштабную задачу на алмазном наборе данных следующим образом:

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 

linear scalelog scale

вот некоторые примеры данных... и я думаю, что вижу проблему. Первоначальный расплавленный набор данных, возможно, составлял ~ 10 ^ 8 рядов. Может быть, номера строк используются для статистики?

> 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")

UPDATE:

Номера строк не являются проблемой. Вот те же самые данные, которые были взяты с использованием той же оси X-оси и цвета заливки, и масштабирование полностью корректно:

> 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

enter image description hereenter image description here

Ответы

Ответ 1

geom_bar и scale_y_log10 (или любой логарифмический масштаб) не работают хорошо и не дают ожидаемых результатов.

Первая фундаментальная проблема состоит в том, что бары переходят к 0, а по логарифмическому масштабу 0 преобразуется в отрицательную бесконечность (что сложно построить). Обломок вокруг этого обычно начинается с 1, а не 0 (так как $\ log (1) = 0 $), ничего не рисует, если было 0 отсчетов, и не беспокоиться об искажении, потому что, если требуется шкала журнала, не заботьтесь о том, чтобы быть выключенным на 1 (не обязательно верно, но...)

Я использую пример diamonds, который показал @dbemarest.

Для этого в общем случае нужно преобразовать координату, а не масштаб (подробнее о разнице позже).

ggplot(diamonds, aes(x=clarity, fill=cut)) +
  geom_bar() +
  coord_trans(ytrans="log10")

Но это дает ошибку

Error in if (length(from) == 1 || abs(from[1] - from[2]) < 1e-06) return(mean(to)) : 
  missing value where TRUE/FALSE needed

которая возникает из проблемы отрицательной бесконечности.

Когда вы используете масштабное преобразование, преобразование применяется к данным, затем создаются статистические данные и компоновки, тогда шкалы помечены в обратном преобразовании (грубо). Вы можете видеть, что происходит, вызывая сами расчеты.

DF <- ddply(diamonds, .(clarity, cut), summarise, n=length(clarity))
DF$log10n <- log10(DF$n)

который дает

> 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

Если мы построим это обычным способом, получим ожидаемый график штриховки:

ggplot(DF, aes(x=clarity, y=n, fill=cut)) + 
  geom_bar(stat="identity")

enter image description here

и масштабирование оси y дает ту же проблему, что и использование не предварительно суммированных данных.

ggplot(DF, aes(x=clarity, y=n, fill=cut)) +
  geom_bar(stat="identity") +
  scale_y_log10()

enter image description here

Мы можем видеть, как эта проблема возникает при построении значений log10() подсчетов.

ggplot(DF, aes(x=clarity, y=log10n, fill=cut)) +
  geom_bar(stat="identity")

enter image description here

Это выглядит так же, как с scale_y_log10, но метки - 0, 5, 10,... вместо 10 ^ 0, 10 ^ 5, 10 ^ 10,...

Таким образом, использование scale_y_log10 делает подсчеты, преобразует их в журналы, складывает эти журналы и отображает шкалу в форме анти-журнала. Однако журналы стеков не являются линейными преобразованиями, поэтому то, что вы просили, не имеет никакого смысла.

Суть в том, что уложенные столбчатые диаграммы в масштабе шкалы не имеют большого смысла, потому что они не могут начинаться с 0 (где нижняя часть панели должна быть), а сравнение частей бара не является разумным, поскольку их размер зависит от того, где они находятся в стеке. Считается вместо чего-то вроде:

ggplot(diamonds, aes(x=clarity, y=..count.., colour=cut)) + 
  geom_point(stat="bin") +
  scale_y_log10()

enter image description here

Или, если вы действительно хотите получить общее количество для групп, которые обычно укладывают бары, вы можете сделать что-то вроде:

ggplot(diamonds, aes(x=clarity, y=..count..)) + 
  geom_point(aes(colour=cut), stat="bin") +
  geom_point(stat="bin", colour="black") +
  scale_y_log10()

enter image description here