ggplot2: Как изменить ширину ящиков в соответствии с другой переменной? - PullRequest
3 голосов
/ 04 марта 2020

Я создал коробку, показывающую расстояние рассеивания $dist некоторых видов $spe, и я хотел бы, чтобы ширина коробок была пропорциональна плотности регенерации этих видов. Я использовал "varwidth" и weight aestheti c, как показано ниже, но это все еще не правильно, так как оно все равно пропорционально количеству наблюдений, а не только плотности регенерации ...

( для плотности я вычислил пропорцию для каждого вида, так что она составляет от 10 до 100. Она указана в столбце data_dist2$prop2)

p <- ggplot(data_dist2, aes(x = reorder(spe, prop2), y = dist)) + 
  coord_flip() + 
  geom_boxplot(varwidth = TRUE, alpha=0.3, aes(weight=data_dist2$prop2), fill='grey10')

Не могли бы вы представить, как сделать коробку точно пропорционально моей prop2 колонке?

Репродуктивный пример:

structure(list(spe = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L), .Label = c("Abies concolor", "Picea abies", "Sequoia semp."
), class = "factor"), dist = c(0, 0, 3, 3, 4, 4, 25, 46, 59, 
113, 113, 9, 12, 12, 12, 15, 22, 22, 22, 22, 35, 35, 36, 49, 
85, 85, 90, 5, 5, 1, 1, 8, 13, 48, 48, 52, 52, 52, 65, 89), prop2 = c(92.17, 
92.17, 92.17, 92.17, 92.17, 92.17, 92.17, 92.17, 92.17, 92.17, 
92.17, 10.9, 10.9, 10.9, 10.9, 10.9, 10.9, 10.9, 10.9, 10.9, 
10.9, 10.9, 10.9, 10.9, 10.9, 10.9, 10.9, 100, 100, 100, 100, 
100, 100, 100, 100, 100, 100, 100, 100, 100)), row.names = c(NA, 
-40L), class = "data.frame")

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

Мифф превосходит меня, но в любом случае вот мой ответ. Как сказал Мифф, вы можете взвесить ширину как prop2.

ggplot(data_dist2, aes(x = reorder(spe, prop2), y = dist)) + 
 geom_boxplot(aes(weight = prop2), 
              varwidth = TRUE,
              fill='grey10', alpha=0.3) +
 coord_flip()

enter image description here

Но geom_boxplot() неявно принимает во внимание размер выборки , Так что вам нужно разделить это по весам. Вот как это можно сделать с помощью data.table.

library(data.table)
setDT(data_dist2) # convert to data.table
data_dist2[, weight := prop2 / .N, by = spe] # Divide prop2 by sample size for each species

ggplot(data_dist2, aes(x = reorder(spe, prop2), y = dist)) + 
  geom_boxplot(aes(weight = weight),  # note weight = weight, not weight = prop2
               varwidth = TRUE,
               fill='grey10', alpha=0.3) +
  coord_flip()

enter image description here

0 голосов
/ 04 марта 2020

Вес, похоже, не предназначен именно для этого, но вы можете немного его взломать. Прежде всего обратите внимание, что вес, данный каждой группе, является суммой весов наблюдений, поэтому, если у вас есть различное количество наблюдений для каждого вида, то вам может потребоваться изменить prop2 на текущее значение, деленное на количество наблюдений в группе. (Из вашего примера я не могу сказать, применимо ли это)

Затем обратите внимание, что ширина пропорциональна квадрату root веса, поэтому измените код, чтобы изменить его на:

p <- ggplot(data_dist2, aes(x = reorder(spe, prop2), y = dist)) + 
     coord_flip() + 
     geom_boxplot(varwidth = TRUE, alpha=0.3, aes(weight=data_dist2$prop2^2), fill='grey10')
...