У меня возникают проблемы с добавлением p-значений в ggplot, когда ось является логарифмической, а все отображаемые значения значительно ниже 1. Кажется, что независимо от того, где я говорю функции поместить p-значение, она всегда ставит его на или выше 1, что часто портит мою шкалу.
MRE:
library(ggplot2)
library(ggpubr)
df <- data.frame("group" = rep(c("A", "B", "C", "D", "E"), each = 5),
"value" = exp(seq(-10,-9, length.out = 25)))
stat_df <- ggpubr::compare_means(formula = value ~ group, data = df, method = "wilcox.test")[1:3,]
p <- ggplot(data = df, aes(x = group, y = value)) +
geom_boxplot() +
ggpubr::stat_pvalue_manual(data = stat_df, y.position = 1e-4, step.increase = 0) +
scale_y_continuous(trans = "log10")
plot(p)
который производит:
Как видите, несмотря на то, что я сказал ggpubr установить p-значение в 1e-4, вместо этого он установил его в 1 (1e0). Для значений выше 1 вы можете просто дать ему log10 значения, которое вы хотите отобразить (например, y.position = 11
отображает его как 1e11), но если вы попытаетесь ввести значение 0 или отрицательное значение для y.position
, он не будет объявиться; в частности, вы получаете следующее:
Warning messages:
1: In self$trans$transform(x) : NaNs produced
2: Transformation introduced infinite values in continuous y-axis
3: Removed 3 rows containing non-finite values (stat_bracket).
Я открыт для использования других пакетов для построения p-значений, ggpubr::stat_pvalue_manual до сих пор был наиболее гибким и полезным для моих целей. Единственный обходной путь, который я нашел для этой проблемы, — это очень хакерское решение с использованием функции scales::pseudo_log_trans и некоторыми причудливыми результатами проб и ошибок, но это далеко не идеальное решение, поскольку оно создает оси, отличные от обычного преобразования log10.
У меня есть два решения для вас:
Поэкспериментируйте с аргументами vjust
и bracket.nudge.y
в stat_pvalue_manual
, чтобы найти оптимальные значения для использования. Это решение по-прежнему преобразует ось с помощью scale_y_continuous
.
library(ggplot2)
ggplot(data = df, aes(x = group, y = value)) +
geom_boxplot() +
ggpubr::stat_pvalue_manual(data = stat_df, y.position = 1,
step.increase = 0, vjust = 0.1,
bracket.nudge.y = -4.9, tip.length = 0.001) +
scale_y_continuous(trans = "log10")
Это решение отказывается от использования scale_y_continuous
для логарифмического преобразования оси, где преобразование выполняется на самом value
. Затем используйте scale_y_continuous
, чтобы отформатировать ось Y в желаемом формате.
ggplot(data = df, aes(x = group, y = log10(value))) +
geom_boxplot() +
ggpubr::stat_pvalue_manual(data = stat_df, y.position = log10(1e-04)) +
scale_y_continuous(labels = \(x) formatC(10^x, format = "e", digits = 1))
Created on 2023-01-14 with reprex v2.0.2
Большое спасибо. Второе решение - это то, с которым я пошел. У меня были коллеги, которые пошли по этому пути (преобразование самих данных) и надеялись избежать этого, но без особой веской причины, кроме того, что это иногда делает разрыв оси немного странным. Первое решение кажется мне слишком хакерским, и у меня есть опасения по поводу попытки сделать это программно (мне нужно сделать много графиков), но я очень ценю его полноту!