R разумно принимает решение о par-mfrow в функции

Я хочу распечатать вывод в соответствии с количеством переменных, которые имеют более 10 уникальных значений в кадре данных. Это может быть любое количество переменных. Я ищу способ реализовать это, чтобы настроить окно графика идеально для количества переменных.

Типа должно быть так:

  • 2 вары -> 1 на 2
  • 3 вары -> 1 на 3
  • 4 переменные -> 2 на 2
  • 5 переменных -> 2 на 3
  • 6 переменных -> 2 на 3
  • .....
  • .....
  • 16 переменных -> 4 на 4
  • 16+ переменных -> 4 на 4

Есть ли для этого логическая формула;

Как превратить это в успешный par(mfrow=(c(x,y)))?

Кроме того, как убедиться, что при достижении номинала до click для следующего окна я не могу щелкнуть, когда у меня больше 16, а вместо этого просто перезаписывает предыдущие графики.


r par
person PascalVKooten    schedule 25.01.2013    source источник
comment
Я не совсем понимаю, чего вы хотите добиться. Похоже, вы хотели бы огранить сюжет? Если это так, вы можете использовать ggplot2.   -  person Roland    schedule 25.01.2013
comment
@Roland Не все функции/пакеты используют ggplot2 для построения графиков, а фасетирование отличается от того, что mfrow делает с устройством построения графиков.   -  person Gavin Simpson    schedule 25.01.2013
comment
Ни один из приведенных ниже ответов, по-видимому, не касается вопроса об использовании щелчка для перехода к следующему графику, когда номер графика равен >16.   -  person Marc in the box    schedule 25.01.2013
comment
@GavinSimpson Я хорошо знаю об этом и сам часто использую базовую графику. Но, как я уже сказал, я даже не понимаю вопроса. Первое предложение может означать многое.   -  person Roland    schedule 25.01.2013
comment
@Marcinthebox Вы не можете легко это сделать. locator(1) в цикле, если индекс цикла > 16, 32 и т. д., заставит пользователя щелкнуть график. devAskNewPage() можно использовать для подсказки в консоли.   -  person Gavin Simpson    schedule 25.01.2013
comment
@Marcinthebox Я обновил свой ответ, как я упомянул выше. Легче, чем я думал...   -  person Gavin Simpson    schedule 25.01.2013
comment
@GavinSimpson - отлично выглядит, Гэвин. Не знал, что locatorможно использовать. Я знал, что должно быть что-то вроде devAskNewPage, но не мог найти. Спасибо!   -  person Marc in the box    schedule 25.01.2013
comment
Почему ответ получил пять голосов, а вопрос только один?   -  person PascalVKooten    schedule 26.01.2013


Ответы (1)


Получение количества строк и столбцов для устройства

n2mfrow() был разработан для этой цели, хотя он имеет тенденцию изменять строки быстрее, чем столбцы, поэтому это противоположно тому, что вы хотите. Например:

> n2mfrow(2)
[1] 2 1

указывает 2 строки по 1 столбцу. Конечно, rev() позволяет легко получить желаемый результат:

> rev(n2mfrow(3))
[1] 1 3

Вот вывод из n2mfrow() для от 2 до 16 графиков со столбцами, изменяющимися быстрее:

t(sapply(2:16, function(x) rev(n2mfrow(x))))

> t(sapply(2:16, function(x) rev(n2mfrow(x))))
      [,1] [,2]
 [1,]    1    2
 [2,]    1    3
 [3,]    2    2
 [4,]    2    3
 [5,]    2    3
 [6,]    3    3
 [7,]    3    3
 [8,]    3    3
 [9,]    3    4
[10,]    3    4
[11,]    3    4
[12,]    4    4
[13,]    4    4
[14,]    4    4
[15,]    4    4

Сделать это интерактивным

Для бита «нажмите после 16». Если вы рисуете в цикле for(i in numplots), когда i> 16 вызовите devAskNewPage(ask = TRUE), и это предложит пользователю активировать следующий график.

Например:

np <- 18 ## number of plots
rc <- ifelse(np > 16, 16, np)
op <- par(mfrow = rev(n2mfrow(rc)))
for(i in seq_len(np)) {
  if(i == 2) {
    devAskNewPage(ask = TRUE)
  }
  plot(1:10)
}
par(op)
devAskNewPage(ask = FALSE)

То же самое можно сделать с помощью locator(1), чтобы заставить щелчок перемещаться по графикам после 16, но для этого нужно немного больше работы:

np <- 18 ## number of plots
rc <- ifelse(np > 16, 16, np)
op <- par(mfrow = rev(n2mfrow(rc)))
for(i in seq_len(np)) {
  if((i %% 16) + 1 == 2 && i > 1) {
    message("Page filled. Click on device to continue...")
    locator(1)
  }
  plot(1:10)
}
par(op)
person Gavin Simpson    schedule 25.01.2013
comment
Возможно, даже лучше не использовать rev(). Я должен подумать об этом. - person PascalVKooten; 25.01.2013
comment
если вам нужны регионы с неравным размером, функция layout() предоставляет альтернативу.. - person agstudy; 25.01.2013
comment
У меня работает devAskNewPage. В моем случае мне пришлось вычесть случаи целого числа цикла for i - the amount of ordinal variables %% 16 == 0. - person PascalVKooten; 25.01.2013
comment
@Dualinity с devAskNewPage() вам нужно вызвать его только один раз, так как он влияет только на новую страницу устройства, а не на окно графика. Смотрите мой обновленный ответ - вам нужно включить его только после завершения сюжета 1. Если вы установите его перед циклом, то перед отрисовкой первого графика вас спросят, а это не то, что нам нужно. - person Gavin Simpson; 25.01.2013
comment
@GavinSimpson Попался. Изменено на: if ((i - ord) == 16) {devAskNewPage(ask = TRUE)} (внутри цикла) - person PascalVKooten; 25.01.2013
comment
Я использовал это сейчас в течение некоторого времени, но я не удовлетворен. Я хотел бы, чтобы он продолжал выполнять код, поэтому я хотел бы, чтобы он все обрабатывал, а не ждал. Только окно сюжета должно ждать. Вы знаете, возможно ли это? - person PascalVKooten; 01.02.2013
comment
@Dualinity Нет, насколько мне известно, это невозможно, поскольку R не возвращает управление, пока вы не щелкнете и т. д. Вы можете использовать механизм истории сюжетов, нарисовать все графики, а затем просмотреть их. Но это другой вопрос. - person Gavin Simpson; 01.02.2013