ggplot scale_y_log10 () проблема - PullRequest
       9

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

26 голосов
/ 29 февраля 2012

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

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

спасибо, Зак cp


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

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 scale log 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 here enter image description here

1 Ответ

37 голосов
/ 01 марта 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...