R - гистограммы с общими / одинаковыми осями x и y - PullRequest
0 голосов
/ 27 февраля 2020

Я хочу построить две гистограммы, где диапазоны x и y одинаковы для обоих. Прочитав несколько постов, я решил использовать ggplot2, geom_histogram дважды. В первый раз я создаю графики без построения графиков для каждого интересующего набора данных с намерением получить максимальные значения осей y / count и x среди всех интересующих графиков. Например, имея два графика, если для первого ymax_1 = 10 для другого ymax_2 = 15, то оба графика будут иметь диапазон осей y как минимум от 0 до 15. Аналогично для оси x.

После этого графика я беру значения ymax / xmax и строю гистограммы, как и ранее, с добавлением xlim (0, xmax) и ylim (0, ymax). Однако, когда я делаю это, количество отсчетов меняется. Более конкретно, на первых графиках, где я не указал xlim / ylim, я получаю ggplot_build (ggplot (...) + geom_histogram (...)) ymax = 2000, но когда я использую xlim во второй раз, я получаю ymax = 4000. Тем не менее, на 1-м графике у меня есть ymax = 2000, и, следовательно, во второй раз гистограммы отображаются неправильно. Когда я удаляю опцию xlim, я получаю тот же результат.

Как и почему опция xlim влияет на количество отсчетов? Я надеюсь, что это было понятно.

df = read.table( paste( path, f, sep = "/"), header = TRUE, fill = TRUE, sep = ",", stringsAsFactors = TRUE)
measure = colnames( df)[ 7]
combs = unique( df[, c( 'A', 'B', 'C')])
# order combs in specific order to get a specific sequence of plots
combs = combs[ with( combs, order( B, C, A)), ]
bns = lst()
xmxs = lst()
ymxs = lst()
for( j in seq( 1, length( combs[ , 1]), 2)) {
 if( combs[ j, 2] == combs[ j, 3]) {
  next
 }
 tmp = subset( df, A == combs[ j, 1] & B == combs[ j, 2] & C == combs[ j, 3], select = c( measure))
 # Freedman – Diaconis rule, "On the histogram as a density estimator: L2 theory"
 bw = 2 * IQR( tmp[ , 1]) / ( length( tmp[ , 1])^(1/3))
 bns[[ j]] = ceiling( ( max( tmp[ , 1]) - min( tmp[ , 1])) / bw)

 plots[[ j]] = ggplot( tmp, aes_string( measure)) + geom_histogram( bins = bns[[ j]], aes( fill = ..count..))
 histg = ggplot_build( plots[[ j]])$data[[ 1]]
 ymxs[[ j]] = max( histg$count)
 xmxs[[ j]] = max( histg$x)

 tmp = subset( df, A == combs[ j + 1, 1] & B == combs[ j + 1, 2] & C == combs[ j + 1, 3], select = c( measure))
 # Freedman – Diaconis rule, "On the histogram as a density estimator: L2 theory"
 bw = 2 * IQR( tmp[ , 1]) / ( length( tmp[ , 1])^(1/3))
 bns[[ j + 1]] = ceiling( ( max( tmp[ , 1]) - min( tmp[ , 1])) / bw)

 plots[[ j + 1]] = ggplot( tmp, aes_string( measure)) + geom_histogram( bins = bns[[ j + 1]], aes( fill = ..count..))
 histg = ggplot_build( plots[[ j + 1]])$data[[ 1]]
 ymxs[[ j + 1]] = max( histg$count)
 xmxs[[ j + 1]] = max( histg$x)
 if( ymxs[[ j]] > ymxs[[ j + 1]]) {
  ymxs[[ j + 1]] = ymxs[[ j]]
 }
 else {
  ymxs[[ j]] = ymxs[[ j + 1]]
 }
 if( xmxs[[ j]] > xmxs[[ j + 1]]) {
  xmxs[[ j + 1]] = xmxs[[ j]]
 }
 else {
  xmxs[[ j]] = xmxs[[ j + 1]]
 }
}
pplots = lst()
for( j in 1 : length( combs[ , 1])) {
 if( combs[ j, 2] == combs[ j, 3]) {
  next
 }
 tmp = subset( df, A == combs[ j, 1] & B == combs[ j, 2] & C == combs[ j, 3], select = c( measure))
 avg = sprintf( "%.2f", mean( tmp[ , 1]))
 stdv = sprintf( "%.2f", std( tmp[ , 1]))
 count = length( tmp[ , 1])
 entities[[ j]] = paste( combs[ j, 1], " ", combs[ j, 2], " vs ", combs[ j, 3])
pplots[[ j]] = ggplot( tmp, aes_string( measure)) +
 geom_histogram( bins = bns[[ j]], aes( fill = ..count..)) +
 # xlim( 0, 1.2*xmxs[[ j]]) +
 # ylim( 0, 1.2*ymxs[[ j]]) +
 ggtitle( bquote( atop( paste( .(entities[[ j]])), paste( mu, " = ", .( avg), ", ", sigma, " = ", .( stdv), ", #cells = ", .( count), sep = " ")))) +
 theme( plot.title = element_text( size = 20), axis.text = element_text( size = 12), axis.title = element_text( size = 15))
 }

 # plot every two plots because the Reference.Population is the same
 for( j in seq( 1, length( plots), 2)) {
 fileext = str_remove_all( entities[[ j]], 'N')
 filename_hi = paste( gsub( '.{4}$', '', f), "_distribution_", fileext, ".png", sep = "")
 png( filename = paste( path, filename_hi, sep = "/"))
 grid.draw( rbind( ggplotGrob( pplots[[ j]]), ggplotGrob( pplots[[ j + 1]]), size = "last"))
 dev.off()
 }

Итак, в приведенном выше коде plots содержит начальные графики, из которых я получаю минимальное и максимальное значения для осей y, x, а pplots содержит графики что я в конце концов планирую, используя опции xlim/ylim. Однако, например,

max( plots[[ 8]]$data[[ 1]]$count) != max( plots[[ 8]]$data[[ 1]]$count)

, когда я использую опцию xlim. Первый дает 1947, а другой дает 4529 для моих данных.

Спасибо

1 Ответ

2 голосов
/ 27 февраля 2020

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

В этом примере я объединю iris$Sepal.Length и mtcars$disp .

range(mtcars$disp)
# [1]  71.1 472.0
range(iris$Sepal.Length)
# [1] 4.3 7.9

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

400 * (range(iris$Sepal.Length) - 4)
# [1]  120 1560

, если вам нужно что-то подобное для ваших данных.

Отсюда, объедините соответствующие поля:

combined_dat <- rbind(
  cbind.data.frame(src = "iris Sepal.Length", val = 400 * (iris[, c("Sepal.Length")] - 4)),
  cbind.data.frame(src = "mtcars disp*", val = mtcars[, c("disp")])
)

head(combined_dat)
#                 src val
# 1 iris Sepal.Length 440
# 2 iris Sepal.Length 360
# 3 iris Sepal.Length 280
# 4 iris Sepal.Length 240
# 5 iris Sepal.Length 400
# 6 iris Sepal.Length 560

tail(combined_dat)
#              src   val
# 177 mtcars disp* 120.3
# 178 mtcars disp*  95.1
# 179 mtcars disp* 351.0
# 180 mtcars disp* 145.0
# 181 mtcars disp* 301.0
# 182 mtcars disp* 121.0

И затем построите график.

ggplot(combined_dat, aes(val)) +
  geom_histogram() +
  facet_wrap(~ src, ncol = 1)
# `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

combining histograms

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...