добавление полос ошибок и полос значимости в двоичные данные ggplot

У меня есть следующий набор данных:

df <- data.frame(replicate(2,sample(0:1,30,rep=TRUE)))
df <- reshape(data=df, varying=list(1:2), 
        direction="long", 
        times = names(df), 
        timevar="Type",
        v.names="Score")

и для создания гистограммы я использую

ggplot(df ,aes(x=Score, fill = Type))+
  geom_bar(position="dodge", color="black")

что дает нам

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

Я хочу добавить планки ошибок, похожие на

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

для градуированных данных я бы просто использовал add = mean_ci, но добавление его в эту функцию ничего не делает

ggplot(df ,aes(x=Score, fill = Type), add = "mean_ci")+
  geom_bar(position="dodge", color="black")

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

Как мне получить хорошие бары ошибок для моей гистограммы двоичных данных?

Кроме того, я также хотел бы добавить столбцы значимости, чтобы гистограмма в конечном итоге выглядела примерно так:

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

Однако я не могу понять, как это сделать с набором данных, похожим на тот, который у меня есть выше.

Буду признателен за любую оказанную помощь.


person Icewaffle    schedule 14.05.2021    source источник


Ответы (1)


Из исходного df просто создайте еще один кадр данных, используя таблицу, и вычислите оттуда количество и sd. биномиальная переменная, поэтому здесь используется дисперсия, определенная как np (1-p):

df <- data.frame(replicate(2,sample(0:1,30,rep=TRUE)))
df1 <- reshape(data=df, varying=list(1:2), 
              direction="long", 
              times = names(df), 
              timevar="Type",
              v.names="Score")

t1 <- as.data.frame(table(df$X1))
t1$Type <- "X1"
t1$sd <- sqrt(sum(t1$Freq)*t1$Freq/sum(t1$Freq)*(1-t1$Freq/sum(t1$Freq)))
t2 <- as.data.frame(table(df$X2))
t2$Type <- "X2"
t2$sd <- sqrt(sum(t2$Freq)*t2$Freq/sum(t2$Freq)*(1-t2$Freq/sum(t2$Freq)))
df_tbl <- rbind(t1,t2)
names(df_tbl) <- c("Score","count","Type","sd")
df_tbl$marg <- df_tbl$count + df_tbl$sd + 1
                            
y0 <- max(df_tbl[which(df_tbl$Score==0),'marg'])
y1 <- max(df_tbl[which(df_tbl$Score==1),'marg'])
prob0 <- prop.test(c(nrow(df)-sum(df$X1), nrow(df)-sum(df$X2)), c(nrow(df), nrow(df)))
prob1 <- prop.test(c(sum(df$X1), sum(df$X2)), c(nrow(df), nrow(df)))
prob <- c(prob0$p.value, prob1$p.value)
prob_sig <- as.character(cut(prob,breaks=c(-1,0.0005,0.001,0.01,max(prob)),
                       labels=c("***","**","*","NS")))

ggplot(df_tbl, aes(x=Score, y=count, fill=Type)) + 
  geom_bar(stat="identity", color="black", 
           position=position_dodge()) +
  geom_errorbar(aes(ymin=count-sd, ymax=count+sd), width=.2,
                position=position_dodge(.9)) +
  ylim(c(0,max(df_tbl$count+df_tbl$sd)+4)) +
  geom_segment(aes(x = 0.8, xend = 1.2, y = y0, yend = y0)) +
  geom_segment(aes(x = 1.8, xend = 2.2, y = y1, yend = y1)) +
  geom_text(aes(x = 1, y = y0 + 0.5, label=prob_sig[1])) +
  geom_text(aes(x = 2, y = y1 + 0.5, label=prob_sig[2]))

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

person Recap_Hessian    schedule 14.05.2021
comment
Спасибо за ваш полезный ответ, однако я не очень понимаю, что происходит после df_tbl$marg и всего, что касается столбцов значимости - я ищу способ сравнить пропорции x1 и x2 0s, а также x1 и x2 1s, чтобы увидеть, существенно ли они различаются (что-то похожее на stat_compare_means, но для двоичных данных. В идеале также со сплошными полосами значимости с «крючками» в конце. - person Icewaffle; 14.05.2021
comment
@Icewaffle Для этого вам нужно будет выполнить prop.test. Я обновил код, чтобы использовать правильные значения вероятности. Вы не можете точно сделать планки ошибок (с «крючками») для них, так как вы выполняете межгрупповое сравнение. Либо вставьте эти крючки вручную через другой geom_segment, либо выберите форму линии и т. д., чтобы они были различимы. Надеюсь, поможет! - person Recap_Hessian; 14.05.2021
comment
Спасибо, очень полезно! И последний вопрос: представляют ли эти планки погрешностей стандартное отклонение или доверительный интервал? Я забыл указать это, но я ищу доверительный интервал. - person Icewaffle; 14.05.2021
comment
@Icewaffle Я использовал стандарт. отклонение, но чтобы получить доверительный интервал 95%, вы можете сделать ymin=count-1.96*sd/sqrt(nrow(df)), ymax=count+1.96*sd/sqrt(nrow(df)) внутри geom_errorbar. - person Recap_Hessian; 17.05.2021