ggplot в R, чтобы добавить значимость звездочке против контрольной группы по нескольким переменным

#r #ggplot2

#r #ggplot2

Вопрос:

У меня есть гистограммы, но я хотел бы запустить Wilcox.test внутри каждого «grp1», сравнивая столбцы с элементом управления для этой группы, а затем ставя звездочку, если она значима.

Я видел «compare_means» для получения сравнений, но я пытаюсь сделать это автоматизированным, а не ручным. Будет ли «geom_signif» или «stat_compare_means» делать это? Может кто-нибудь помочь с этим? Большое вам спасибо.

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

 y <- c(runif(100,0,4.5),runif(100,3,6),runif(100,4,7))
grp1 <- sample(c("A","B","C","D"),size = 300, replace = TRUE)
grp2 <- rep(c("High","Med","Contrl"),each=100)
dataset <- data.frame(y,grp1,grp2)

means <- aggregate(y~grp1 grp2,data=dataset,mean)
sd <- aggregate(y~grp1 grp2,data=dataset,function(x){sd(x)})

means.all <- merge(sd,means,by=c("grp1","grp2"))
names(means.all)[3:4] <- c("sd","y.mean")

library(ggplot2)
p<- ggplot(means.all, aes(x=grp1, y=y.mean, fill=grp2))  
  geom_bar(stat="identity", color="black", 
           position=position_dodge())  
  geom_errorbar(aes(ymin=y.mean-sd, ymax=y.mean sd), width=.2,
                position=position_dodge(.9))
p

compare_means(y~grp2,data = dataset[dataset$grp1=="A",],method="wilcox.test")
  

Ответ №1:

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

 library(ggplot2)
library(ggpubr)
library(patchwork)
#Split data
List <- split(means.all,means.all$grp1)
#Function for plot
myfun <- function(x)
{
  #Ref group
  rg <- paste0(unique(x$grp1),'.','Contrl')
  #Plot
  G <- ggplot(x, aes(x=interaction(grp1,grp2), y=y.mean, fill=grp2))  
    geom_bar(stat="identity", color="black", 
             position=position_dodge())  
    geom_errorbar(aes(ymin=y.mean-sd, ymax=y.mean sd), width=.2,
                  position=position_dodge(.9)) 
    stat_compare_means(ref.group = rg,label =  "p.signif",method = "wilcox.test",label.y = 7) 
    theme(axis.text.x = element_blank()) 
    xlab(unique(x$grp1))
  return(G)
}
#Apply
Lplot <- lapply(List, myfun)
#Wrap plots
wrap_plots(Lplot,nrow = 1) plot_layout(guides = 'collect')
  

Вывод:

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

Рассмотрим это обновление, которое принимает значения для звездочек, хранящихся в новом фрейме данных:

 #Create p-vals dataset
List2 <- split(dataset,dataset$grp1)
#p-val function
mypval <- function(x)
{
  y <- compare_means(y~grp2,data = x,method="wilcox.test")
  y <- y[,c('group2', 'group1','p.signif')]
  names(y)<-c('grp2','grp1','p.signif')
  y <- y[y$grp2=='Contrl',]
  y$grp2 <- y$grp1
  y <- rbind(y,data.frame(grp2='Contrl',grp1='',p.signif=''))
  y$grp1 <- unique(x$grp1)
  y$y.mean=7
  return(y)
}
#Apply
dfpvals <- lapply(List2, mypval)
df <- do.call(rbind,dfpvals)
#Plot
ggplot(means.all, aes(x=grp1, y=y.mean, fill=grp2,group=grp2))  
  geom_bar(stat="identity", color="black", 
           position=position_dodge())  
  geom_errorbar(aes(ymin=y.mean-sd, ymax=y.mean sd), width=.2,
                position=position_dodge(.9)) 
  geom_text(data=df,aes(x=grp1, y=y.mean,group=grp2,label=p.signif),
            position=position_dodge(0.9))
  

Вывод:

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

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

1. Когда я запускаю «compare_means» для того же набора данных (grp1 = A), он показывает, что существуют существенные различия (p = 9,70e-15). Написанный вами код выполняет тест Уилкоксена для средних значений, а не для полного набора данных. Могу ли я просто добавить оператор aes в функцию «stat_compare_means»?

2. @Schatzi121 Попробуйте с этим, я не уверен, как вы получили значение p, возможно, добавьте этот эскиз к вашему вопросу, отредактировав его, чтобы мы могли лучше понять!

3. Хорошо, я добавил строку кода, выполняющую сравнение. Я почти уверен, что «stat_compare_mean» тоже должен это сделать, мне просто нужно передать в него полный набор данных. Можете ли вы помочь с этим? Могу ли я просто добавить еще один ввод в функцию?

4. На самом деле я запускаю код в PowerBI, который запускает его каждый раз при обновлении страницы или данных. Поэтому в идеале я бы хотел, чтобы он потреблял как можно меньше вычислительной мощности, потому что это замедлит его. Я подумал, что мы могли бы использовать тот же код, что и у вас, но передавать целые наборы данных, а затем запускать среднюю агрегатную функцию в функции «myfun».

5. @Schatzi121 Это очень странно, не могли бы вы попробовать перезапустить R и только загрузить ggplot2 , и ggpubr , возможно, это конфликт с другим пакетом, или вы используете Power BI?