Как обеспечить ggplot position_dodge по категориям без данных?

Я пытаюсь использовать position_dodge на ggplot, чтобы получить ящики из двух разных сигналов (ind), разделяющих одни и те же категории (cat). Когда есть категория с данными для одного сигнала, но не для другого, полевая диаграмма для сигнала с данными охватывает все горизонтальные интервалы и не соблюдает инструкцию position_dodge для этой конкретной категории. Есть ли способ заставить ggplot применять правило уклонения? Как видно из приведенного ниже примера, сигнал x не имеет данных для категории B, поэтому он теряет пространство, зарезервированное position_dodge. Я бы хотел этого избежать.

Спасибо заранее.

data<-data.frame(cat=c('A','A','A','A','B','B','A','A','A','A','B','B'), 
                 values=c(3,2,1,4,NA,NA,4,5,6,7,8,9), 
                 ind=c('x','x','x','x','x','x','y','y','y','y','y','y'))

print(ggplot() +
        scale_colour_hue(guide='none') +
      geom_boxplot(
           aes(x=as.factor(cat), y=values, 
               fill=ind), 
           position=position_dodge(width=.60), 
           data=data,
           outlier.size = 1.2,
           na.rm=T))

graph with original problem

ОБНОВЛЕНИЕ ПРОГРЕССА

После некоторых обходных решений я придумал результат, который я искал... (вид)

data            <- data.frame(
cat=c('A','A','A','A','B','B','A','A','A','A','B','B','B'), 
values=c(3,2,1,4,NA,NA,4,5,6,7,8,9, 0), 
ind=c('x','x','x','x','x','x','y','y','y','y','y','y','x'))

p  <- ggplot() +
      scale_colour_hue(guide='none') +
      geom_boxplot(aes(x=as.factor(cat), y=values, fill=ind),
      position=position_dodge(width=.60), 
      data=data,
      outlier.size = 1.2,
      na.rm=T) +
      geom_line(aes(x=x, y=y), 
                data=data.frame(x=c(0,3),y=rep(0,2)), 
                size = 1, 
                col='white')
print(p)

solution with workaround

Некоторые люди пересматривали использование огранки для эффекта, который я хотел. Граничение не дает мне эффекта, который я ищу. Последний график, который я искал, показан ниже:

final graph

Если вы заметили, белый знак майка в y = 10 будет толще других меток. Эта более толстая линия - это геометрия с размером = 1, которая скрывает нежелательные ящики.

Хотелось бы, чтобы мы могли более легко комбинировать различные объекты геометрии. Я сообщил об этом как об ошибке в Hadley github, но Хэдли сказал, что это то, как position_dodge ведет себя по дизайну. Наверное, я использую ggplot2 нестандартным способом, и обходные пути - это способ решения этих проблем. В любом случае, я надеюсь, что это поможет некоторым из R-пользователей значительно увеличить функциональность ggplot.

Ответ 1

После некоторых обходных решений я придумал результат, который я искал... (вид)

data            <- data.frame(
cat=c('A','A','A','A','B','B','A','A','A','A','B','B','B'), 
values=c(3,2,1,4,NA,NA,4,5,6,7,8,9, 0), 
ind=c('x','x','x','x','x','x','y','y','y','y','y','y','x'))

p  <- ggplot() +
      scale_colour_hue(guide='none') +
      geom_boxplot(aes(x=as.factor(cat), y=values, fill=ind),
      position=position_dodge(width=.60), 
      data=data,
      outlier.size = 1.2,
      na.rm=T) +
      geom_line(aes(x=x, y=y), 
                data=data.frame(x=c(0,3),y=rep(0,2)), 
                size = 1, 
                col='white')
print(p)

solution with workaround

Некоторые люди рекомендовали использовать огранку для эффекта, который я хотел. Граничение не дает мне эффекта, который я ищу. Последний график, который я искал, показан ниже:

final graph

Если вы заметили, белый знак майка в y = 10 будет толще других меток. Эта более толстая линия - это геометрия с размером = 1, которая скрывает нежелательные ящики.

Хотелось бы, чтобы мы могли более легко комбинировать различные объекты геометрии. Я сообщил об этом как об ошибке в Hadley github, но Хэдли сказал, что это то, как position_dodge ведет себя по дизайну. Наверное, я использую ggplot2 нестандартным способом, и обходные пути - это способ решения этих проблем. В любом случае, я надеюсь, что это поможет некоторым из R-пользователей значительно увеличить функциональность ggplot.

Ответ 2

x из B не имеет значений, поэтому вы можете добавить "B", 0, "x", что по существу указывает на отсутствие распределения "значений" для x из B. Медианы и другие процентили равны нулю.

 data<-data.frame(cat=c('A','A','A','A','B','B','A','A','A','A','B','B','B'), 
             values=c(3,2,1,4,NA,NA,4,5,6,7,8,9,0), 
             ind=c('x','x','x','x','x','x','y','y','y','y','y','y','x'))

Также вам не нужно добавлять параметры позиции здесь, потому что, когда вы рассматриваете x как фактор, ggplot - geom_boxplot автоматически уклоняется от сторон.

print(ggplot() +
  scale_colour_hue(guide='none') +
  geom_boxplot(aes(x=as.factor(cat), y=values, fill=ind), 
  data=data,
  outlier.size = 1.2,
  na.rm=T))

Ответ 3

Я просто понял, как использовать огранку из одного из комментариев, опубликованных Хэдли на своем git сайте, поэтому кредиты идут на Хэдли, сопровождающий пакет ggplot2!

Посмотрите, если это то, что вы хотели. Чтобы узнать больше о параметрах настройки усов и других объектов на этом графике, просмотрите эту страницу справки в пакете ggplot2:

?stat_boxplot

data<-data.frame(cat=c('A','A','A','A','B','B','A','A','A','A','B','B'), 
             values=c(3,2,1,4,NA,NA,4,5,6,7,8,9), 
             ind=c('x','x','x','x','x','x','y','y','y','y','y','y'))

p <- ggplot(data = data, aes(factor(cat), values))                     
p + stat_boxplot(geom="boxplot", position = "dodge", width = 0.60, na.rm = TRUE) +  facet_grid(.~ind)

enter image description here

Чтобы добавить цвета к вашему сюжету, который, на мой взгляд, является избыточным, поскольку вы уже украшаете сюжет на основе переменной "ind", попробуйте следующее:

p <- ggplot(data, aes(factor(cat), values, fill = ind))                     
p + stat_boxplot(geom="boxplot", position = "dodge", width = 0.60, na.rm = TRUE) + facet_grid(.~ind)

enter image description here

НТН!