用新浪图显示多个因素

Tib*_*ius 5 r ggplot2 ggforce

注意:我在与Z. Lin讨论后更新了这篇文章.最初,我将我的问题简化为双因素设计(参见" 原始问题 "部分).但是,我的实际数据包含四个因素,需要facet_grid.因此,我在下面提供了一个四因素设计的示例(请参见" 编辑 " 部分).

原始问题

让我们假设我有一个双因素设计,dv作为我的因变量,iv.x和iv.y作为我的因子/自变量.一些快速的样本数据:

DF <- data.frame(dv = rnorm(900), 
                 iv.x = sort(rep(letters[1:3], 300)), 
                 iv.y = rep(sort(rep(rev(letters)[1:3], 100)), 3))
Run Code Online (Sandbox Code Playgroud)

我的目标是分别显示每个条件,就像小提琴图一样可以很好地完成:

ggplot(DF, aes(iv.x, dv, colour=iv.y)) + geom_violin()  
Run Code Online (Sandbox Code Playgroud)

我最近遇到了新浪的情节,我想在这里做同样的事情.不幸的是,新浪图不会这样做,而是折叠数据.

ggplot(DF, aes(iv.x, dv, colour=iv.y)) + geom_sina()
Run Code Online (Sandbox Code Playgroud)

对位置闪避的显式调用也没有帮助,因为这会产生错误消息:

ggplot(DF, aes(iv.x, dv, colour=iv.y)) + geom_sina(position = position_dodge(width = 0.5))
Run Code Online (Sandbox Code Playgroud)

新浪图的作者已经在2016年意识到这个问题:https: //github.com/thomasp85/ggforce/issues/47

我的问题更多的是时间问题.我们很快就想提交一份手稿,而新浪图则是展示我们数据的绝佳方式.任何人都可以想到新浪图的解决方法,这样我仍然可以显示两个因素,例如上面的小提琴情节?

编辑

四因素设计的样本数据:

    DF <- data.frame(dv=rnorm(400), 
             iv.w=sort(rep(letters[1:2],200)),
             iv.x=rep(sort(rep(letters[3:4],100)), 2),
             iv.y=rep(sort(rep(rev(letters)[1:2],50)),4),
             iv.z=rep(sort(rep(letters[5:6],25)),8))
Run Code Online (Sandbox Code Playgroud)

我想用新浪图创建的小提琴图的示例:

    ggplot(DF, aes(iv.x, dv, colour=iv.y)) + 
      facet_grid(iv.w ~ iv.z) +
      geom_violin(aes(y = dv, fill = iv.y), 
          position = position_dodge(width = 1))+
      stat_summary(aes(y = dv, fill = iv.y), fun.y=mean, geom="point", 
          colour="black", show.legend = FALSE, size=.2, 
          position=position_dodge(width=1))+
      stat_summary(aes(y = dv, fill = iv.y), fun.data=mean_cl_normal, geom="errorbar", 
          position=position_dodge(width=1), width=.2, show.legend = FALSE,
          colour="black", size=.2) 
Run Code Online (Sandbox Code Playgroud)

Z.L*_*Lin 3

编辑解决方案,因为 OP 澄清需要方面:

ggplot(DF, aes(x = interaction(iv.y, iv.x), 
               y = dv, fill = iv.y, colour = iv.y)) + 
  facet_grid(iv.w ~ iv.z) +      
  geom_sina() +
  stat_summary(fun.y=mean, geom="point", 
               colour="black", show.legend = FALSE, size=.2, 
               position=position_dodge(width=1))+
  stat_summary(fun.data=mean_cl_normal, geom="errorbar", 
               position=position_dodge(width=1), width=.2, 
               show.legend = FALSE,
               colour="black", size=.2) +
  scale_x_discrete(name = "iv.x", 
                   labels = c("c", "", "d", "")) +
  theme(panel.grid.major.x = element_blank(),
        axis.text.x = element_text(hjust = -4),
        axis.ticks.x = element_blank())
Run Code Online (Sandbox Code Playgroud)

这种方法不是使用小平面来模拟颜色之间的闪避,而是创建一个interaction(colour.variable, x.variable)要映射到 x 轴的新变量。

scale_x_discrete()&中的其余代码theme()用于隐藏默认的 x 轴标签/刻度/网格线。

axis.text.x = element_text(hjust = -4)是一种将 x 轴标签移动到大约正确位置的 hack。它很丑陋,但考虑到用例是用于手稿提交,我假设绘图的大小将是固定的,您只需要调整一次即可。

编辑解决方案

原解决方案

假设您的绘图不需要分面,您可以使用分面模拟外观:

ggplot(DF, aes(x = iv.y, y = dv, colour = iv.y)) +
  geom_sina() + 
  facet_grid(~iv.x, switch = "x") +
  labs(x = "iv.x") +
  theme(axis.text.x = element_blank(),      # hide iv.y labels
        axis.ticks.x = element_blank(),     # hide iv.y ticks
        strip.background = element_blank(), # make facet strip background transparent
        panel.spacing.x = unit(0, "mm"))    # remove horizontal space between facets
Run Code Online (Sandbox Code Playgroud)

阴谋