Pergunta

I want to print output, according to the amount of variables that have more than 10 unique values in a data-frame. This could be any number of variables. I am looking for a way to implement this as to set the plot window to be perfect for the amount of variables.

It kind of should be like:

  • 2 vars -> 1 by 2
  • 3 vars -> 1 by 3
  • 4 vars -> 2 by 2
  • 5 vars -> 2 by 3
  • 6 vars -> 2 by 3
  • .....
  • .....
  • 16 vars -> 4 by 4
  • 16+ vars -> 4 by 4

Is there a logical formula for this;

How to make this into a succesful par(mfrow=(c(x,y)))?

Also, how to make sure when the par limit has been reached, to click for the next window, I can't click when I have more than 16, but instead just overwrites the previous graphs.

Foi útil?

Solução

Getting the number of rows and columns for the device

The n2mfrow() was designed for this purpose, although it tends to vary rows faster than columns so is opposite of what you want. For example:

> n2mfrow(2)
[1] 2 1

indicates 2 rows by 1 column. Of course, rev() makes it easy to get the output you want:

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

Here is output from n2mfrow() for 2 to 16 total plots with columns varying faster:

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

Making this interactive

For the "click after 16" bit. If doing your plotting in a for(i in numplots) loop, when i > 16 call devAskNewPage(ask = TRUE) and that will prompt for user to active next plot.

For example:

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)

A similar thing could be done using locator(1) to force a click to move on post 16 plots, but it needs a bit more work:

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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top