Как аннотировать текст на отдельных аспектах в сюжете взаимодействия (`ggplot2`;` взаимодействия`)?

Я хотел бы иметь разные аннотации (например, p-значения) для каждого аспекта (по одному для каждого наклона моего фактического графика - всего 6). Думаю, я прочитал все сообщения об аннотировании фасетов, наиболее полезными из которых, конечно же, являются main Аннотирование текста на отдельном фасете в ggplot2. Но в моей ситуации это выкидывает ошибки.

Я использую пакет interactions, который предоставляет доступный для редактирования объект ggplot, но вызывает другие проблемы. Вот минимально воспроизводимый пример с использованием mtcars.

# Create the model
mod1 <- lm(wt ~ am * drat * vs, data = mtcars)

# Make the plot
require(interactions)
(p <- interact_plot(mod1,pred="am",modx="drat",mod2="vs"))

введите описание изображения здесь

# Make annotations dataframe
(dat_text <- data.frame(
  text = c("p-value 1", "p-value 2"),
  vs   = c(0, 1)))

# Add annotations to dataframe
require(ggplot2)
p + geom_text(
  data    = dat_text,
  mapping = aes(x = -Inf, y = -Inf, label = text),
  hjust   = -0.1,
  vjust   = -1
)

Это дает: Error in FUN(X[[i]], ...) : object 'modx_group' not found. Также такая же ошибка с 'drat' not found. Я не слишком уверен, как справиться с этой ошибкой (например, какие значения их установить), поэтому я попытался добавить эти столбцы в фрейм данных следующим образом:

# Make annotations dataframe
(dat_text <- data.frame(
  text = c("p-value 1", "p-value 2"),
  vs   = c(0, 1),
  modx_group = c("-1 SD", "+ 1 SD"), # Here ***
  drat = c(-1,1))) # Here ***

# Add annotations to dataframe
p + geom_text(
  data    = dat_text,
  mapping = aes(x = -Inf, y = -Inf, label = text),
  hjust   = -0.1,
  vjust   = -1
)

Но это дает: Insufficient values in manual scale. 4 needed but only 3 provided. Установка modx_group и drat на NA, NA_real_ или даже 0, как указано в другое сообщение, появляется еще одна ошибка: Discrete value supplied to continuous scale.

Я не могу понять эти ошибки в текущем контексте. Я подозреваю, конечно, что это связано с тем, что сюжетный объект interactions был напуган. Также, вероятно, есть что-то очевидное, что я делаю неправильно, но не вижу. Любая помощь будет оценена по достоинству!

Редактировать

Основываясь на ответе @tefan, я смог создать желаемый результат для моего более сложного проекта (с 6 p-значениями, по одному для каждого наклона и конкретными позициями для каждой аннотации), как показано ниже.

<!-- language-all: lang-r -->


# Create the model
mod1 <- lm(wt ~ am * drat * vs, data = mtcars)

# Make the plot
require(interactions)
#> Loading required package: interactions
(p <- interact_plot(mod1,pred="am",modx="drat",mod2="vs"))

# Make annotations dataframes
dat_text <- data.frame(
  text = c("p-value 3", "p-value 6", "p-value 2", "p-value 5", "p-value 1", "p-value 4"),
  mod2_group = c("vs = 0", "vs = 1", "vs = 0", "vs = 1", "vs = 0", "vs = 1"),
  x = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5),
  y = c(3, 2.5, 3.5, 2.75, 4, 3))

# Add annotations to dataframe
require(ggplot2)
#> Loading required package: ggplot2
p + geom_text(data = dat_text,
              mapping = aes(x = x, y = y, label = text),
              inherit.aes = FALSE)

Создано 10 июня 2020 г. пакетом REPEX (v0.3.0)


person RemPsyc    schedule 09.06.2020    source источник


Ответы (1)


Проблема в том, что geom_text наследует глобальную эстетику от interact_plot. Чтобы этого не произошло, просто добавьте inherit.aes = FALSE. Тем не менее, вы должны добавить переменную фасетирования в df надписи. Чтобы предотвратить это, ggplot2 добавляет глиф для текста в легенде, просто добавьте show.legend = FALSE.

# Create the model
mod1 <- lm(wt ~ am * drat * vs, data = mtcars)

# Make the plot
require(interactions)
#> Loading required package: interactions
p <- interact_plot(mod1,pred="am",modx="drat", mod2="vs")

# Have a look at the dataframe
p$data
#> # A tibble: 600 x 6
#>       wt  drat    vs     am modx_group mod2_group
#>    <dbl> <dbl> <dbl>  <dbl> <fct>      <fct>     
#>  1  4.13  3.06     0 0      - 1 SD     vs = 0    
#>  2  4.12  3.06     0 0.0101 - 1 SD     vs = 0    
#>  3  4.12  3.06     0 0.0202 - 1 SD     vs = 0    
#>  4  4.11  3.06     0 0.0303 - 1 SD     vs = 0    
#>  5  4.11  3.06     0 0.0404 - 1 SD     vs = 0    
#>  6  4.10  3.06     0 0.0505 - 1 SD     vs = 0    
#>  7  4.10  3.06     0 0.0606 - 1 SD     vs = 0    
#>  8  4.09  3.06     0 0.0707 - 1 SD     vs = 0    
#>  9  4.09  3.06     0 0.0808 - 1 SD     vs = 0    
#> 10  4.08  3.06     0 0.0909 - 1 SD     vs = 0    
#> # ... with 590 more rows

(dat_text <- data.frame(
  text = c("p-value 1", "p-value 2"),
  mod2_group   = c("vs = 0", "vs = 1")))
#>        text mod2_group
#> 1 p-value 1     vs = 0
#> 2 p-value 2     vs = 1


# Add annotations to dataframe
require(ggplot2)
#> Loading required package: ggplot2
p + geom_text(
  data    = dat_text,
  mapping = aes(x = .5, y = 2, label = text), inherit.aes = FALSE, show.legend = FALSE,
  hjust   = -0.1,
  vjust   = -1
)

Создано 09.06.2020 с помощью пакета REPEX (v0.3.0)

person stefan    schedule 09.06.2020
comment
Прошу прощения, что мой вопрос был непонятен. Я не спрашиваю о метках графика x y, а скорее о том, как аннотировать (т.е. добавлять текст непосредственно на график, а не изменять метки), например p-значения для отдельных уклонов. Я изменил test1 и test2 на p-value 1 и p-value 2 для большей ясности. - person RemPsyc; 09.06.2020
comment
Хорошо, прежде всего, спасибо! Кажется, это работает. Я заметил, что здесь действительно имеет значение modx_group = c (- 1 SD, - 1 SD). Потому что он работал с вашим скопированным кодом, но не тогда, когда я его набирал. В конце концов я заметил, что единственная разница заключалась в том, что мне не хватало места между минусом и 1 SD. Когда это будет исправлено, вам действительно не понадобится wt and am. Также следует отметить, что mod2_group и modx_group должны иметь эти конкретные значения, иначе это не сработает. Возможно, вы могли бы прокомментировать это в своем ответе для будущих читателей. - person RemPsyc; 09.06.2020
comment
Единственная другая проблема, почему это решение не полностью работает для меня, заключается в том, что оно добавляет нежелательную букву a в легенде для каждой строки уровня драта. И я не вижу очевидного объяснения того, почему это так. Однако это довольно проблематично. Я обязательно приму ваш ответ, если мы сможем исправить и эту новую проблему. - person RemPsyc; 09.06.2020
comment
Не большая проблема. Подождите минуту. И я предложу еще лучшее решение. (; - person stefan; 09.06.2020
comment
Теперь я знаю, для чего inherit.aes годится ... до сих пор не использовал. - person stefan; 09.06.2020
comment
Чудесно! Действительно, лучший и более элегантный ответ. На самом деле я пробовал использовать наследовать.aes = FALSE, но в моем случае каждая метка отображалась дважды (на каждом фасете; вероятно, потому, что у меня не было mod2_group, как вы упомянули!). Еще раз спасибо! - person RemPsyc; 09.06.2020
comment
К вашему сведению, я отредактировал свой вопрос в конце, чтобы показать адаптированный окончательный код с 6 p-значениями в определенных местах и ​​результирующей цифрой. - person RemPsyc; 10.06.2020
comment
Привет, @RemPsyc. Я бы сказал, что это был пример хорошего сотрудничества. Я смотрел ваше редактирование. Не уверен, что вы пробовали. Однако, как вы можете видеть из моего редактирования вашего редактирования, можно использовать только один df и один вызов geom_text для добавления аннотаций. Надеюсь, это вам подходит. С наилучшими пожеланиями, Стефан. - person stefan; 10.06.2020
comment
Это восхитительно! Большое спасибо! Я не знал, что это сработает, если повторить те же два фактора mod2_group несколько раз. Все-таки так просто! :) - person RemPsyc; 10.06.2020