【问题标题】:Problems adapting the y-axis to 2x2 ANOVA bargraph using R and ggplot [duplicate]使用 R 和 ggplot 将 y 轴调整为 2x2 ANOVA 条形图的问题 [重复]
【发布时间】:2023-03-14 23:14:01
【问题描述】:

我不是 Pro R 用户,但我已经尝试了多种方法,但找不到问题的解决方案。

我为 2x2 ANOVA 创建了一个条形图,包括误差条、APA 主题和基于此网站的自定义颜色:https://sakaluk.wordpress.com/2015/08/27/6-make-it-pretty-plotting-2-way-interactions-with-ggplot2/ 它工作得很好,但 y 轴从 0 开始,尽管我的比例范围仅为 1 - 7。我正在尝试调整轴,但出现奇怪的错误。

这就是我所做的:

# see https://sakaluk.wordpress.com/2015/08/27/6-make-it-pretty-plotting-2-way-interactions-with-ggplot2/

interactionMeans(anova.2)
plot(interactionMeans(anova.2))

#using ggplot
install.packages("ggplot2")
library(ggplot2)

# create factors with value 

GIFTSTUDY1DATA$PRICE <- ifelse (Scenario == 3 | Scenario == 4, 1, -1 )
table(GIFTSTUDY1DATA$PRICE)
GIFTSTUDY1DATA$PRICE <- factor(GIFTSTUDY1DATA$PRICE, levels = c(-1, +1),
                                  labels = c("2 expensive", "1 inexpensive"))

GIFTSTUDY1DATA$AFFECT <- ifelse (Scenario == 1 | Scenario == 3, -1, +1 )
table(GIFTSTUDY1DATA$AFFECT)
GIFTSTUDY1DATA$AFFECT <- factor(GIFTSTUDY1DATA$AFFECT,
                                 levels = c(-1,1),
                                 labels = c("poor", "rich"))
# get descriptives

dat2 <- describeBy(EVALUATION,list(GIFTSTUDY1DATA$PRICE,GIFTSTUDY1DATA$AFFECT), 
                  mat=TRUE,digits=2)
dat2

names(dat2)[names(dat2) == 'group1'] = 'Price'
names(dat2)[names(dat2) == 'group2'] = 'Affect'

dat2$se = dat2$sd/sqrt(dat2$n)
# error bars +/- 1 SE
limits = aes(ymax = mean + se, ymin=mean - se)
dodge = position_dodge(width=0.9)

# set layout

apatheme=theme_light()+
  theme(panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        panel.border=element_blank(),
        axis.line=element_line(),
        text=element_text(family='Arial'))

#plot

p=ggplot(dat2, aes(x = Affect, y = mean, fill = Price))+
  geom_bar(stat='identity', position=dodge)+
  geom_errorbar(limits, position=dodge, width=0.15)+
  apatheme+
  ylab('mean gift evaluatoin')+
  scale_fill_manual(values=c("yellowgreen","skyblue4"))
p

这给了我这个数字:

https://i.stack.imgur.com/MwdVo.png

现在,如果我尝试使用 ylim 或 scale_y_continous 更改 y 轴

p + ylim(1,7)
p + scale_y_continuous(limits = c(1,7))

我得到了一个带有 y 轴的图表,但没有条形图和一条错误消息说明

删除了包含缺失值的 4 行 (geom_bar)。

https://i.stack.imgur.com/p66H8.png

使用

p + expand_limits(y=c(1,7))
p 

更改 y 轴的上端,但仍包含零!

我做错了什么?我是否必须在不使用 geom_bar 的情况下重新开始? 提前致谢。

【问题讨论】:

    标签: r ggplot2 graph yaxis


    【解决方案1】:

    虽然 Magnus Nordmo 的回答很有帮助,但我想补充一下 ggplot2 为何如此行事的原因。

    考虑以下情节(友情提示geom_col()geom_bar(stat = "identity") 的简写):

    df <- data.frame(x = letters[1:7],
                     y = 1:7)
    
    g <- ggplot(df, aes(x, y)) +
      geom_col()
    g
    

    您可以清楚地看到条形看起来像矩形。检查底层绘图数据,确认条形图参数化为矩形,参数化为 xmin/xmax/ymin/ymax:

    > layer_data(g)
      x y PANEL group ymin ymax xmin xmax colour   fill size linetype alpha
    1 1 1     1     1    0    1 0.55 1.45     NA grey35  0.5        1    NA
    2 2 2     1     2    0    2 1.55 2.45     NA grey35  0.5        1    NA
    3 3 3     1     3    0    3 2.55 3.45     NA grey35  0.5        1    NA
    4 4 4     1     4    0    4 3.55 4.45     NA grey35  0.5        1    NA
    5 5 5     1     5    0    5 4.55 5.45     NA grey35  0.5        1    NA
    6 6 6     1     6    0    6 5.55 6.45     NA grey35  0.5        1    NA
    7 7 7     1     7    0    7 6.55 7.45     NA grey35  0.5        1    NA
    

    现在考虑以下情节:

    g2 <- ggplot(df, aes(x, y)) +
      geom_col() +
      scale_y_continuous(limits = c(1, 7))
    

    这个是空的,反映了你发布的案例。检查基础数据会产生以下结果:

    > layer_data(g2)
      y x PANEL group ymin ymax xmin xmax colour   fill size linetype alpha
    1 1 1     1     1   NA    1 0.55 1.45     NA grey35  0.5        1    NA
    2 2 2     1     2   NA    2 1.55 2.45     NA grey35  0.5        1    NA
    3 3 3     1     3   NA    3 2.55 3.45     NA grey35  0.5        1    NA
    4 4 4     1     4   NA    4 3.55 4.45     NA grey35  0.5        1    NA
    5 5 5     1     5   NA    5 4.55 5.45     NA grey35  0.5        1    NA
    6 6 6     1     6   NA    6 5.55 6.45     NA grey35  0.5        1    NA
    7 7 7     1     7   NA    7 6.55 7.45     NA grey35  0.5        1    NA
    

    您可以看到ymin 列被NAs 替换。此行为取决于scale_y_continuous()oob(越界)参数,默认为scales::censor() 函数。此检查器(替换为 NA)任何超出轴限制的值,其中包括应该是 ymin 列的 0。因此,无法绘制矩形。

    有两种方法可以解决这个问题。正如 Magnus 建议的那样,一位候选人确实在 coord_cartesian() 函数中使用了 ylim 参数:

    ggplot(df, aes(x, y)) +
      geom_col() +
      coord_cartesian(ylim = c(1, 7))
    

    coord_* 函数内指定限制会导致图形对象被剪裁。当您关闭剪辑时,您可以看到这一点:

    ggplot(df, aes(x, y)) +
      geom_col() +
      coord_cartesian(ylim = c(1, 7), clip = "off")
    

    另一种选择是在scale_y_continuous 中使用替代的oob 参数,例如scales::squish

    g3 <- ggplot(df, aes(x, y)) +
      geom_col() +
      scale_y_continuous(limits = c(1, 7), 
                         oob = scales::squish)
    g3
    

    它的作用是用最接近的限制替换限制之外的任何值,例如0 的ymin 变为 1:

    > layer_data(g3)
      y x PANEL group ymin ymax xmin xmax colour   fill size linetype alpha
    1 1 1     1     1    1    1 0.55 1.45     NA grey35  0.5        1    NA
    2 2 2     1     2    1    2 1.55 2.45     NA grey35  0.5        1    NA
    3 3 3     1     3    1    3 2.55 3.45     NA grey35  0.5        1    NA
    4 4 4     1     4    1    4 3.55 4.45     NA grey35  0.5        1    NA
    5 5 5     1     5    1    5 4.55 5.45     NA grey35  0.5        1    NA
    6 6 6     1     6    1    6 5.55 6.45     NA grey35  0.5        1    NA
    7 7 7     1     7    1    7 6.55 7.45     NA grey35  0.5        1    NA
    

    您可以做的另一件事是为oob 参数提供一个自定义函数,该函数只是返回它的输入。由于默认情况下剪辑是打开的,这反映了coord_cartesian(ylim = c(1,7)) 的情况:

    ggplot(df, aes(x, y)) +
      geom_col() +
      scale_y_continuous(limits = c(1, 7), 
                         oob = function(x, ...){x})
    

    我希望这能澄清这里发生的事情。

    【讨论】:

    • 太棒了,这是对正在发生的事情的非常清晰的解释!非常感谢您提供这个。
    • teun,我喜欢这个 - 我认为在更明显的线程上会更合适:stackoverflow.com/questions/10365167/…
    • 令人惊讶的是,您不仅能够敏锐地识别重复的问题,而且能够识别“规范”的答案。
    • 回家, - 已将您的答案添加为社区 wiki。随意声明所有权,我只是认为这对未来的人会有帮助。 stackoverflow.com/questions/10365167/…
    【解决方案2】:

    我也遇到过类似的问题,通过替换解决了

    scale_y_continuous(limits = c()coord_cartesian(ylim = c())

    我认为这可能对你有用。

    这是一个例子:

    library(tidyverse)
    
    ggplot(mtcars,aes(factor(am),hp)) + 
       geom_bar(stat = "identity") + 
       coord_cartesian(ylim = c(1000,3000))
    

    另见链接: Google R Discussion

    【讨论】:

    • 是的!它有效:) 太好了!非常感谢,马格努斯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多