【问题标题】:Underscore plot in RR中的下划线图
【发布时间】:2019-08-22 20:25:27
【问题描述】:

简介和当前完成的工作

[注意:对于那些感兴趣的人,我在最后提供了代码来复制我的示例。]

我有一些数据,我进行了方差分析,得到了 Tukey 的成对比较:

model1 = aov(trt ~ grp, data = df)
anova(model1)

> TukeyHSD(model1)
          diff         lwr       upr     p adj
B-A 0.03481504 -0.40533118 0.4749613 0.9968007
C-A 0.36140489 -0.07874134 0.8015511 0.1448379
D-A 1.53825179  1.09810556 1.9783980 0.0000000
C-B 0.32658985 -0.11355638 0.7667361 0.2166301
D-B 1.50343674  1.06329052 1.9435830 0.0000000
D-C 1.17684690  0.73670067 1.6169931 0.0000000

我还可以绘制 Tukey 的成对比较

> plot(TukeyHSD(model1))

我们可以从 Tukey 的置信区间和图中看出 A-BB-CA-C 没有显着差异。

问题

我被要求创建一个叫做“下划线图”的东西,描述如下:

我们将组均值绘制在实线上,并在组均值之间绘制一条线段,以表明这两个特定组之间没有显着差异。

获得手段并不难:

> aggregate(df$trt ~ df$grp, FUN = mean)
  df$grp   df$trt
1      A 2.032086
2      B 2.066901
3      C 2.393491
4      D 3.570338

期望的输出

使用本示例中的数据,所需的绘图应如下所示:

组之间存在一条没有显着差异的线段(即,Tukey 指出的 A-BB-CA-C 之间的线段)。

注意:请注意,上面的图不是按比例绘制的,它是在主题演讲中创建的,仅用于说明目的。

有没有办法使用 R 获得上述“下划线图”(使用基本 R 或 ggplot2 等库)?

编辑

这是我用来创建上述示例的代码:

library(data.table)

set.seed(3)
A = runif(20, 1,3)
A = data.frame(A, rep("A", length(A)))
B = runif(20, 1.25,3.25)
B = data.frame(B, rep("B", length(B)))
C = runif(20, 1.5,3.5)
C = data.frame(C, rep("C", length(C)))
D = runif(20, 2.75,4.25)
D = data.frame(D, rep("D", length(D)))

df = list(A, B, C, D)
df = rbindlist(df)

colnames(df) = c("trt", "grp")

【问题讨论】:

  • @d.b 我已经编辑了问题并提供了用于在问题中创建值的代码。代码可以在问题的末尾找到。我使用了set.seed,所以这个示例数据应该是可重现的。
  • @Matt:谢谢你的建议。 mmcplot 创建了一个二维点阵,“下划线图”是一维的。

标签: r ggplot2 plot graphics


【解决方案1】:

这是下划线图的 ggplot 版本。我们将加载tidyverse 包,它会加载ggplot2dplyr 和tidyverse 中的其他一些包。我们创建了一个系数数据框来绘制组名、系数值和垂直段,并创建一个非显着对的数据框来生成水平下划线。

library(tidyverse)

model1 = aov(trt ~ grp, data=df)

# Get coefficients and label coefficients with names of levels
coefs = coef(model1)
coefs[2:4] = coefs[2:4] + coefs[1]
names(coefs) = levels(model1$model$grp)

# Get non-significant pairs
pairs = TukeyHSD(model1)$grp %>% 
  as.data.frame() %>% 
  rownames_to_column(var="pair") %>% 
  # Keep only non-significant pairs
  filter(`p adj` > 0.05) %>% 
  # Add coefficients to TukeyHSD results
  separate(pair, c("pair1","pair2"), sep="-", remove=FALSE) %>% 
  mutate(start = coefs[match(pair1, names(coefs))],
         end = coefs[match(pair2, names(coefs))]) %>% 
  # Stagger vertical positions of segments
  mutate(ypos = seq(-0.03, -0.04, length=3))

# Turn coefs into a data frame
coefs = enframe(coefs, name="grp", value="coef")

ggplot(coefs, aes(x=coef)) +
  geom_hline(yintercept=0) +
  geom_segment(aes(x=coef, xend=coef), y=0.008, yend=-0.008, colour="blue") +
  geom_text(aes(label=grp, y=0.011), size=4, vjust=0) +
  geom_text(aes(label=sprintf("%1.2f", coef)), y=-0.01, size=3, angle=-90, hjust=0) +
  geom_segment(data=pairs, aes(group=pair, x=start, xend=end, y=ypos, yend=ypos),
               colour="red", size=1) +
  scale_y_continuous(limits=c(-0.05,0.04)) +
  theme_void()

【讨论】:

  • 谢谢!这有效,但是我不得不做一个小的改变。我不得不将 pairs = TukeyHSD(model1)$grp 更改为 pairs = TukeyHSD(model1)$'df$grp' 并且成功了!
  • 那是因为您的模型公式包含数据框名称。最好使用 data 参数将数据框传递到函数中,并在公式中使用裸列名称。我忘记将其添加到我现在已更新的答案中。
  • 太好了,感谢您的澄清!
  • This SO question 显示了在模型公式中使用数据框名称时可能出现的问题,而不是使用 data 参数将其传递给建模函数。
【解决方案2】:

基础R

d1 = data.frame(TukeyHSD(model1)[[1]])
inds = which(sign(d1$lwr) * (d1$upr) <= 0)
non_sig = lapply(strsplit(row.names(d1)[inds], "-"), sort)

d2 = aggregate(df$trt ~ df$grp, FUN=mean)

graphics.off()
windows(width = 400, height = 200)
par("mai" = c(0.2, 0.2, 0.2, 0.2))
plot(d2$`df$trt`, rep(1, NROW(d2)),
     xlim = c(min(d2$`df$trt`) - 0.1, max(d2$`df$trt`) + 0.1), lwd = 2,
     type = "l",
     ann = FALSE, axes = FALSE)
segments(x0 = d2$`df$trt`,
         y0 = rep(0.9, NROW(d2)),
         x1 = d2$`df$trt`,
         y1 = rep(1.1, NROW(d2)),
         lwd = 2)
text(x = d2$`df$trt`, y = rep(0.8, NROW(d2)), labels = round(d2$`df$trt`, 2), srt = 90)
text(x = d2$`df$trt`, y = rep(0.75, NROW(d2)), labels = d2$`df$grp`)
lapply(seq_along(non_sig), function(i){
    lines(cbind(d2$`df$trt`[match(non_sig[[i]], d2$`df$grp`)], rep(0.9 - 0.01 * i, 2)))
})

【讨论】:

    猜你喜欢
    • 2014-07-22
    • 2020-06-18
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    • 2013-08-22
    相关资源
    最近更新 更多