Как сгруппировать уже сложенные бары при использовании R ggplot и geom_bar

#r #ggplot2 #geom-bar

#r #ggplot2 #геометрическая панель

Вопрос:

Я использую следующий myggdf фрейм данных в R

 structure(list(Signature = c(1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 
5L, 1L, 3L, 5L), Sample = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L), .Label = c("F.vcf", "G.vcf", "H.vcf", 
"I.vcf"), class = "factor"), Contribution = c(638.885179211473, 
403.558378092796, 237.864729405206, 621.475592580731, 507.076811680132, 
844.111458945023, 340.773496994329, 693.189161464458, 868.648293203769, 
350.293155215537, 796.162462388531, 393.009724831982), label = c("lung", 
"lung", "lung", "lung", "lung", "lung", "ovary", "ovary", "ovary", 
"ovary", "ovary", "ovary")), row.names = c(NA, -12L), class = "data.frame")
  
    Signature Sample Contribution label
1          1  F.vcf     638.8852  lung
2          3  F.vcf     403.5584  lung
3          5  F.vcf     237.8647  lung
4          1  G.vcf     621.4756  lung
5          3  G.vcf     507.0768  lung
6          5  G.vcf     844.1115  lung
7          1  H.vcf     340.7735 ovary
8          3  H.vcf     693.1892 ovary
9          5  H.vcf     868.6483 ovary
10         1  I.vcf     350.2932 ovary
11         3  I.vcf     796.1625 ovary
12         5  I.vcf     393.0097 ovary
  

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

Используя следующий код

 ggplot(myggdf, aes(x=Sample, y=Contribution, fill=as.factor(Signature)))  
      geom_bar(stat="identity", position='stack')   facet_grid(~label)
  

возвращает этот график, который не слишком далек от того, что я ожидаю.

Однако, как получить образец, отображаемый только в соответствующем аспекте?

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

Спасибо за любой совет

Комментарии:

1. Пожалуйста, укажите dput версию вашего фрейма данных — его гораздо проще загрузить в локальную среду.

Ответ №1:

Одним из вариантов было бы добавить scales="free_x" в facet_grid :

 library(ggplot2)

myggdf <- structure(list(Signature = c(1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 
                             5L, 1L, 3L, 5L), Sample = c("F.vcf", "F.vcf", "F.vcf", "G.vcf", 
                                                         "G.vcf", "G.vcf", "H.vcf", "H.vcf", "H.vcf", "I.vcf", "I.vcf", 
                                                         "I.vcf"), Contribution = c(638.8852, 403.5584, 237.8647, 621.4756, 
                                                                                    507.0768, 844.1115, 340.7735, 693.1892, 868.6483, 350.2932, 796.1625, 
                                                                                    393.0097), label = c("lung", "lung", "lung", "lung", "lung", 
                                                                                                         "lung", "ovary", "ovary", "ovary", "ovary", "ovary", "ovary")), row.names = c(NA, 
                                                                                                                                                                                       -12L), class = "data.frame")

ggplot(myggdf, aes(x=Sample, y=Contribution, fill=as.factor(Signature)))  
  geom_bar(stat="identity", position='stack')   facet_grid(~label, scales = "free_x")
  

Комментарии:

1. Спасибо @stefan, это то, что я искал!

Ответ №2:

Возможно, одним из вариантов было бы использование interaction() такого. Также вы можете включить scales опцию внутри facet_*() функций для изменения формы оси, как это делает @stefan. Здесь код:

 #Code
ggplot(myggdf, aes(x=interaction(Sample,label), y=Contribution, fill=as.factor(Signature)))  
  geom_bar(stat="identity", position='stack')
  

Вывод:

введите описание изображения здесь

И опция с фасетами подразумевает создание новых переменных, подобных этим:

 library(tidyverse)
#Data and plot
myggdf %>% 
  mutate(Var='var',Newlabel=paste0(Sample,'-',label)) %>%
  ggplot(aes(x=Var, y=Contribution, fill=as.factor(Signature)))  
  geom_bar(stat="identity", position='stack') 
  facet_wrap(.~Newlabel,scales='free')
  

Вывод:

введите описание изображения здесь

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

 #Data and plot 2
myggdf %>% 
  mutate(Var='var',Newlabel=paste0(Sample,'-',label)) %>%
  ggplot(aes(x=Var, y=Contribution, fill=as.factor(Signature)))  
  geom_bar(stat="identity", position='stack') 
  facet_wrap(.~Newlabel,scales='free_x',nrow = 1)
  

Вывод:

введите описание изображения здесь

Некоторые используемые данные:

 #Data
myggdf <- structure(list(Signature = c(1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 
5L, 1L, 3L, 5L), Sample = c("F.vcf", "F.vcf", "F.vcf", "G.vcf", 
"G.vcf", "G.vcf", "H.vcf", "H.vcf", "H.vcf", "I.vcf", "I.vcf", 
"I.vcf"), Contribution = c(638.8852, 403.5584, 237.8647, 621.4756, 
507.0768, 844.1115, 340.7735, 693.1892, 868.6483, 350.2932, 796.1625, 
393.0097), label = c("lung", "lung", "lung", "lung", "lung", 
"lung", "ovary", "ovary", "ovary", "ovary", "ovary", "ovary")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
  

Обновление: для лучшего различия в оси можно настроить метки следующим образом:

 #Data and plot 3
myggdf %>% 
  mutate(Newlabel=paste0(Sample,' (',label,')')) %>%
  ggplot(aes(x=Newlabel, y=Contribution, fill=as.factor(Signature)))  
  geom_bar(stat="identity", position='stack') 
  xlab('Sample-Tissue')
  

Вывод:

введите описание изображения здесь

Комментарии:

1. Спасибо @Duck, мне нравится первый вариант. Хотя читаемость все еще можно улучшить, лучше разделив столбцы, принадлежащие к разным тканям.

2. @ChristopheAntoniewski Да, это возможно, позвольте мне набросать для вас новый код.

3. @ChristopheAntoniewski Я добавил небольшой новый код в заключительной части. Дайте мне знать, если это то, что вы ищете.