Многостраничное расположение решетчатых панелей - PullRequest
2 голосов
/ 11 марта 2012

Я пытаюсь получить многостраничный двухмерный решетчатый график, чтобы на нескольких страницах был одинаковый макет кондиционирования. Вертикальное расположение должно быть

CCC
BBB
AAA

на каждой странице. Я знаю, как сделать это вручную, но код уродлив, особенно если последняя страница заполнена не полностью.

В теме 2010 года я прочитал, что это было "в списке" для ggplot2.

library(lattice)
d = expand.grid(f1 = as.factor(letters[1:10]),
            f2 = as.factor(LETTERS[1:3]),
            x  = 0:10)
d$y = rnorm(nrow(d))
xyplot(y~x|f1+f2,data=d,cex=0.5,pch=16,layout=c(5,3,2))

Обратите внимание, что все A находятся на первой странице, затем B, а затем B и C на последней странице.

Отредактировано по идее Габора

library(lattice)
library(latticeExtra)

# Note: changed so that it does not fill the three pages
d <- expand.grid(f1 = as.factor(letters[1:8]),
            f2 = as.factor(LETTERS[1:3]),
            x  = 0:10)
d$y <- rnorm(nrow(d))
page <- factor((as.numeric(d$f1) - 1) %/% 5 + 1)
# The second (=last) page has different panel sizes
# Using aspect does not help
for(pg in levels(page)) {
  p <- xyplot(y ~ x|f1+f2, data = d[pg == page, ], cex = .5, pch = 16,
          layout = c(5, 3))
  print(useOuterStrips(p))
}

Ответы [ 2 ]

3 голосов
/ 12 марта 2012

Размещение панелей может быть достигнуто написанием новой функции packet.panel, которая автоматически рисует панели в нужных местах.

packet.panel.bycolumn <- function (layout, condlevels, page, row, column, skip) {
  dims <- sapply(condlevels, length)
  if(layout[2] != dims[2]) {
    stop("rows in layout must be equal to rows of second conditioning variable")
  }
  panels.per.row <- layout[1]
  panels.per.column <- layout[2]
  total.columns <- dims[1]
  panels.needed <- total.columns * panels.per.column
  panels.per.page <- layout[1] * layout[2]
  pages.needed <- ceiling(panels.needed / panels.per.page)
  empty.columns <- (panels.per.row - total.columns) %% panels.per.row
  panel.matrix <- rbind(matrix(1:panels.needed,ncol=panels.per.column),
                        matrix(NA, nrow=empty.columns, ncol=panels.per.column))
  panel.order <- as.vector(aperm(array(panel.matrix,
                                       dim=c(panels.per.row, pages.needed, panels.per.column)),
                                 c(1,3,2)))
  packet.order <- do.call(expand.grid, condlevels)[panel.order,]
  panel.number <- 1 + (page - 1) * panels.per.page + (row - 1) * panels.per.row + (column - 1)
  out <- as.numeric(packet.order[panel.number, ])
  if (any(is.na(out))) out <- NULL
  out
}

useOuterStrips изменит макет, но впоследствии его можно будет изменить. Желаемый результат может быть достигнут следующим образом:

p <- xyplot(y~x|f1+f2, data=d, cex=0.5, pch=16)
p <- useOuterStrips(p)
p <- update(p, layout=c(5,3))
plot(p, packet.panel=packet.panel.bycolumn)

enter image description here

enter image description here

3 голосов
/ 11 марта 2012

Предполагается, что требуется две страницы с:

  • C в первой строке каждой страницы
  • B во второй строке каждой страницы
  • A в последнем ряду каждой страницы

и

  • abcde в столбцах первой страницы и
  • fghij в столбцах второй страницы

затем попробуйте это:

p <- xyplot(y ~ x | f2:f1, data = d, cex = 0.5, pch = 16, layout = c(5, 3, 2))
ix <- c(aperm(array(1:30, c(5, 2, 3)), c(1, 3, 2)))
p[ix]

Обязательно обратите внимание на выравнивающее изменение в формуле xyplot.

страница за раз

Другой подход - выводить страницу за раз:

page <- factor((as.numeric(d$f1) - 1) %/% 5 + 1)
for(pg in levels(page)) {
    p <- xyplot(y ~ x|f1+f2, data = d[pg == page, ], cex = .5, pch = 16)
    plot(p, layout = c(5, 3))
}
...