Вычисление сюжетных подклассов в R с использованием dendextend

Я рисую Tanglegrams в R, используя dendextend. Мне интересно, можно ли построить несколько подзаговоров с помощью par(mfrow = c(2,2))?

Я не могу понять это.

Спасибо

library(dendextend)
dend15 <- c(1:5) %>% dist %>% hclust(method = "average") %>% as.dendrogram
dend15 <- dend15 %>% set("labels_to_char")
dend51 <- dend15 %>% set("labels", as.character(5:1)) %>% match_order_by_labels(dend15)
dends_15_51 <- dendlist(dend15, dend51)

par(mfrow = c(2,2))
tanglegram(dends_15_51)
tanglegram(dends_15_51)
tanglegram(dends_15_51)
tanglegram(dends_15_51)

Ответ 1

tl; dr: Невозможно использовать par(mfrow=...) с функцией tanglegram, но это возможно с помощью layout.

Объяснение: Если вы посмотрите ближе к функции tanglegram, вы увидите (methods(tanglegram)), что под ним существует несколько методов, среди которых dendextend:::tanglegram.dendrogram, который вызывается нарисуйте tanglegram (как видно из функции dendextend:::tanglegram.dendlist).

Внутри этой функции есть вызов layout:

layout(matrix(1:3, nrow = 1), widths = columns_width) 

Это "стирает" предыдущую настройку par(mfrow=c(2, 2)) и меняет ее на c(1, 3) (только для "времени" функции, хотя, поскольку в конце функции значение reset...),

В самом деле, на странице справки layout говорится:

Эти функции полностью несовместимы с другими механизмами организации графиков на устройстве: par (mfrow), par (mfcol) и split.screen.

Вывод: Если вы хотите построить несколько таблеток в одном и том же "окне", вам нужно будет использовать вызов layout (с 12 подстроками: 2 строки и 6 столбцов) перед вызывает tanglegram и подавляет вызов layout внутри tanglegram с помощью аргумента just_one=FALSE.

Пример рисования нескольких таблеток:

Используя приведенный ниже код, вы можете получить желаемый график (я поместил по умолчанию ширину по умолчанию для макета):

layout(matrix(1:12, nrow=2, byrow=TRUE), widths=rep(c(5, 3, 5), 2))
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)

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

Это было сделано путем обновления пакета dendextend, в котором: я изменил 2 функции tanglegram.dendrogram и tanglegram.dendlist, чтобы добавить параметр just_one, который по умолчанию равен TRUE и изменил строку layout в tanglegram.dendrogram to:

 if (just_one) layout(matrix(1:3, nrow = 1), widths = columns_width)

Я также подавил параметры reset par и, конечно, изменил вызов в tanglegram.dendlist (теперь называемый tanglegram.dendlist_mod), поэтому он вызывает новую измененную функцию, включает параметр just_one и передает его на измененная функция tanglegram.dendrogram.

Ответ 2

Вместо создания комбинированного графика в одном графическом устройстве вы можете создать несколько графиков и упорядочить их, когда вы поместите их в документ. Пакет knitr упрощает это, используя fig.show = "hold", чтобы удерживать несколько графиков, созданных в одном блоке R, и указывая соответствующий out.width, например. 50% для двух графиков подряд, когда графики помещаются в документ.

Например, в файле R markdown (.Rmd) у вас может быть

```{r, fig.show = "hold", out.width = "50%", echo = FALSE}
suppressPackageStartupMessages(library(dendextend))
dend15 <- c(1:5) %>% dist %>% hclust(method = "average") %>% as.dendrogram
dend15 <- dend15 %>% set("labels_to_char")
dend51 <- dend15 %>% set("labels", as.character(5:1)) %>% match_order_by_labels(dend15)
dends_15_51 <- dendlist(dend15, dend51)
tanglegram(dends_15_51, margin_outer = 1)
plot.new()
tanglegram(dends_15_51, margin_outer = 1)
plot.new()
tanglegram(dends_15_51, margin_outer = 1)
plot.new()
tanglegram(dends_15_51, margin_outer = 1)
```

который при knit ted в HTML выглядел бы следующим образом:

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

В код внесено несколько изменений:

  • Подавленные сообщения о запуске пакета из dendextend.
  • Увеличено значение по умолчанию margin_outer, чтобы избежать совпадения меток оси x от соседних графиков.
  • Добавлен plot.new() между вызовами tanglegram, иначе следующий график будет нарисован поверх предыдущего (это результат tanglegram с использованием layout и вообще не нужен при создании нескольких участки).

Такой же подход может использоваться в файлах .Rnw. Если вы компилируете в PDF (через LaTeX), вы можете добавить заголовок и подзаголовки фигуры, см. knitr demo # 067 - Параметры графики для более подробно.