如何将geom_bar,geom_point和geom_line合并为一个图形?

时间:2019-09-03 00:58:20

标签: r ggplot2 data-visualization geom-bar

我正在尝试通过三个并行条件(CET,RES,END)和对干预的响应(高或低,即CET_Hi,CET_Lo等)可视化两个时间点(干预前后)的连续数据点

我想创建一个条形图,在X轴上显示每个条件的平均输出,并用单独的条形表示时间(前和后)。然后,我想在Pre和Post上的各个Subject数据点上覆盖线,以连接Subject数据点,并按颜色对响应进行分组。

我已经成功使用ggplot2和geom_bar函数创建了条形图。我也有geom_point按条件覆盖各个点,但是无法使位置与时间对齐。

ggplot(Leg_Press_Summary, aes(x=Condition, y=Leg_Press, fill=as.factor(Time))) + 
geom_bar(stat="identity", position=position_dodge()) + 
scale_fill_brewer(palette="Blues", name = "Time", labels = c("Pre", "Post")) +
geom_point(data=Phys_Data, aes(x=Condition, y=Leg_Press, colour=Response, fill=as.factor(Time))) +
geom_line(data=Phys_Data, aes(x=Condition, y=Leg_Press, group=Subject)) + 
labs(title="Leg Press", x="Condition", y ="Leg Press (kg)")

我希望geom_points可以根据时间进行定位,但是,对于每种情况,它们仅在Pre和Post条之间的垂直线上指向堆叠。

我的结果:

My ggplot2 creation

我要重新创建的图:

Figure I'm trying to recreate

我该如何解决?

下面包含的数据集,我忘了包含在原始帖子中。

LegPress
# A tibble: 36 x 5
Subject  Time Condition Response Leg_Press

6     1 CET       CET_Hi        212.
6     2 CET       CET_Hi        300 
9     1 CET       CET_Lo        350 
9     2 CET       CET_Lo        370 
14     1 CET       CET_Hi        330 
14     2 CET       CET_Hi        450 
26     1 CET       CET_Hi        180 
26     2 CET       CET_Hi        250 
28     1 CET       CET_Lo        230 
28     2 CET       CET_Lo        275 
29     1 CET       CET_Lo        330 
29     2 CET       CET_Lo        325 
2     1 RES       RES_Hi        142.
2     2 RES       RES_Hi        225 
16     1 RES       RES_Lo        280 
16     2 RES       RES_Lo        320 
19     1 RES       RES_Hi        205 
19     2 RES       RES_Hi        295 
27     1 RES       RES_Hi        175 
27     2 RES       RES_Hi        260 
31     1 RES       RES_Lo        340 
31     2 RES       RES_Lo        370 
32     1 RES       RES_Lo        310 
32     2 RES       RES_Lo        370 
8     1 END       END_Lo        205 
8     2 END       END_Lo        250 
13     1 END       END_Hi        310 
13     2 END       END_Hi        320 
20     1 END       END_Hi        200 
20     2 END       END_Hi        185 
24     1 END       END_Lo        260 
24     2 END       END_Lo        270 
25     1 END       END_Hi        210 
25     2 END       END_Hi        235 
30     1 END       END_Lo        250 
30     2 END       END_Lo        245 

2 个答案:

答案 0 :(得分:1)

正在加载软件包:

library(dplyr); library(tidyr); library(ggplot2)

粗略地基于图形设置示例数据:

set.seed(4)
df <- data.frame(Time = rep(rep(c("pre", "post"), each=20),3),
                 Condition = rep(c("CET", "END", "RES"), each=40),
                 Leg_Press = c(rnorm(20, 275, 20), rnorm(20, 325, 20), rnorm(20, 245, 20), rnorm(320, 251, 20), rnorm(20, 247, 10), rnorm(320, 305, 10)))

针对每个条件和时间段生成平均值,最小值和最大值的摘要表:

dat <- df %>% group_by(Time, Condition) %>% summarise(mean = mean(Leg_Press), max = max(Leg_Press), min = min(Leg_Press))
dat$Time <- factor(dat$Time, level=c("pre", "post"))

# # A tibble: 6 x 5
# # Groups:   Time [2]
#   Time  Condition  mean   max   min
#   <fct> <fct>     <dbl> <dbl> <dbl>
# 1 post  CET        283.  373.  209.
# 2 post  END        277.  329.  200.
# 3 post  RES        278.  328.  215.
# 4 pre   CET        273.  326.  191.
# 5 pre   END        276.  323.  197.
# 6 pre   RES        276.  329.  204.

按条件进行腿部按压的简单条形图,分为前后时间段:

ggplot(dat, aes(Condition, mean, fill=Time)) +
      geom_col(position="dodge")

enter image description here

计算每个点的新x值以获取最大值和最小值:

dat <- dat %>% mutate(new.x = ifelse(Time == "pre", -0.25, 0.25) + as.numeric(as.factor(Condition)))

ggplot(data=dat) +
  geom_col(aes(Condition, mean, fill=Time), position="dodge") +
  geom_point(aes(x=new.x, y=max)) +
  geom_point(aes(x=new.x, y=min)) 

enter image description here

要为每个组画线,需要为每个最大值和最小值集提供一个数据框。

max.frame <- dat %>% 
     group_by(Condition) %>% 
     mutate(t2 = Time) %>% 
     spread(Time, max) %>% 
     summarise(x1 = min(new.x), x2 = max(new.x), y1 = mean(pre, na.rm=T), y2 = mean(post, na.rm=T))

# # A tibble: 3 x 5
#   Condition    x1    x2    y1    y2
#   <fct>     <dbl> <dbl> <dbl> <dbl>
# 1 CET        0.75  1.25  326.  373.
# 2 END        1.75  2.25  323.  329.
# 3 RES        2.75  3.25  329.  328.

min.frame <- dat %>% 
      group_by(Condition) %>% 
      mutate(t2 = Time) %>% 
      spread(Time, min) %>% 
      summarise(x1 = min(new.x), x2 = max(new.x), y1 = mean(pre, na.rm=T), y2 = mean(post, na.rm=T))

# # A tibble: 3 x 5
#   Condition    x1    x2    y1    y2
#   <fct>     <dbl> <dbl> <dbl> <dbl>
# 1 CET        0.75  1.25  191.  209.
# 2 END        1.75  2.25  197.  200.
# 3 RES        2.75  3.25  204.  215.

根据三个框架进行绘制:

ggplot() +
  geom_col(data=dat, aes(Condition, mean, fill=Time), position="dodge") +
  geom_segment(data=max.frame, aes(x=x1, y=y1, xend = x2, yend = y2)) +
  geom_segment(data=min.frame, aes(x=x1, y=y1, xend = x2, yend = y2)) +
  geom_point(data=dat, aes(x=new.x, y=max)) +
  geom_point(data=dat, aes(x=new.x, y=min)) 

enter image description here

答案 1 :(得分:0)

它认为您想使用faceting

library(tidyverse)  

Phys_Data <- data.frame(stringsAsFactors=FALSE,
     Subject = c(6, 6, 9, 9, 14, 14, 26, 26, 28, 28, 29, 29, 2, 2, 16, 16, 19,
                 19, 27, 27, 31, 31, 32, 32, 8, 8, 13, 13, 20, 20, 24, 24, 25,
                 25, 30, 30),
        Time = c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
                 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2),
   Condition = c("CET", "CET", "CET", "CET", "CET", "CET", "CET", "CET", "CET",
                 "CET", "CET", "CET", "RES", "RES", "RES", "RES", "RES", "RES",
                 "RES", "RES", "RES", "RES", "RES", "RES", "END", "END", "END",
                 "END", "END", "END", "END", "END", "END", "END", "END", "END"),
    Response = c("CET_Hi", "CET_Hi", "CET_Lo", "CET_Lo", "CET_Hi", "CET_Hi",
                 "CET_Hi", "CET_Hi", "CET_Lo", "CET_Lo", "CET_Lo", "CET_Lo",
                 "RES_Hi", "RES_Hi", "RES_Lo", "RES_Lo", "RES_Hi", "RES_Hi",
                 "RES_Hi", "RES_Hi", "RES_Lo", "RES_Lo", "RES_Lo", "RES_Lo", "END_Lo",
                 "END_Lo", "END_Hi", "END_Hi", "END_Hi", "END_Hi", "END_Lo",
                 "END_Lo", "END_Hi", "END_Hi", "END_Lo", "END_Lo"),
   Leg_Press = c(212, 300, 350, 370, 330, 450, 180, 250, 230, 275, 330, 325,
                 142, 225, 280, 320, 205, 295, 175, 260, 340, 370, 310, 370,
                 205, 250, 310, 320, 200, 185, 260, 270, 210, 235, 250, 245)
)

Phys_Data %>%
  mutate(
    Time = as.factor(Time),
    Response = str_split_fixed(Response, "_", 2)[,2]
  ) %>%
  ggplot(aes(x=Time, y=Leg_Press, fill=Time)) +
    facet_wrap(~Condition, strip.position = "bottom") +
    geom_col(
      data = ~group_by(.x, Time, Condition) %>%
        summarize(Leg_Press = mean(Leg_Press)) %>%
        ungroup()
    ) +
    scale_fill_brewer(palette="Blues", name = "Time", labels = c("Pre", "Post")) +
    geom_point(aes(color=Response)) +
    geom_line(aes(color=Response, group=Subject)) +
    labs(title="Leg Press", x = "Condition", y ="Leg Press (kg)") +
    theme(
      axis.text.x = element_blank(),
      axis.ticks.x = element_blank()
    )

reprex package(v0.3.0)于2019-09-04创建