在第一个轴上使用 free_y 比例并在第二个轴上固定 + facet_grid + ggplot2

Use free_y scale on first axis and fixed on second + facet_grid + ggplot2

有什么方法可以在 ggplot2 的左手(第一)轴上设置 scale = 'free_y' 并在右手(第二)轴上使用固定轴?

我有一个数据集,我需要对一个变量使用自由标度,对另一个变量使用固定标度,但在同一个图上表示两者。为此,我尝试向我的数据添加第二个固定的 y 轴。问题是我找不到任何方法来为第二轴设置固定比例并将其反映在小平面网格中。

这是我目前创建图表的代码 -

#plot weekly seizure date 
p <- ggplot(dfspw_all, aes(x=WkYr, y=Seizures, group = 1)) +  geom_line() + 
  xlab("Week Under Observation") + ggtitle("Average Seizures per Week - To Date") + 
  geom_line(data = dfsl_all, aes(x =WkYr, y = Sleep), color = 'green') +
  scale_y_continuous(
    # Features of the first axis
    name = "Seizures",
    # Add a second axis and specify its features
    sec.axis = sec_axis(~.[0:20], name="Sleep")
  )

p + facet_grid(vars(Name), scales = "free_y") +
  theme(axis.ticks.x=element_blank(),axis.text.x = element_blank())

这是它正在生成的内容(为简单起见,代码中省略了一些细节)-

我需要的是让左边的刻度保持“自由”,让右边的刻度保持在 0-24 之间。

副轴在 ggplot2 中作为装饰实现,它是主轴的变换,所以我不知道这样做的优雅方法,因为它需要副轴公式来了解不同的缩放比例每个方面的因素。

这是一种 hacky 方法,我将每个次级系列缩放到其各自的主要系列,然后为次级系列添加一些手动注释。另一种方法可能是像 一样为每个方面单独制作图,然后使用 patchwork 将它们组合起来。

给定一些假数据,其中主要系列的构面范围不同但次要系列的范围相同:

library(tidyverse)
fake <- tibble(facet = rep(1:3, each = 10),
               x = rep(1:10, times = 3),
               y_prim = (1+sin(x))*facet/2,
               y_sec = (1 + sin(x*3))/2)

ggplot(fake, aes(x, y_prim)) +
  geom_line() + 
  geom_line(aes(y= y_sec), color = "green") +
  facet_wrap(~facet, ncol = 1)

...我们可以将每个次级系列缩放到其主要系列,并为该次级系列添加自定义注释:

fake2 <- fake %>%
  group_by(facet) %>%
  mutate(y_sec_scaled = y_sec/max(y_sec) * (max(y_prim))) %>%
  ungroup()

fake2_labels <- fake %>% 
  group_by(facet) %>%
  summarize(max_prim = max(y_prim), baseline = 0, x_val = 10.5)

ggplot(fake2, aes(x, y_prim)) +
  geom_line() + 
  geom_line(aes(y= y_sec_scaled), color = "green") +
  facet_wrap(~facet, ncol = 1, scales = "free_y") +
  geom_text(data = fake2_labels, aes(x = x_val, y = max_prim, label = "100%"),
            hjust = 0, color = "green") +
  geom_text(data = fake2_labels, aes(x = x_val, y = baseline, label = "0%"),
            hjust = 0, color = "green") +
  coord_cartesian(xlim = c(0, 10), clip = "off") +
  theme(plot.margin = unit(c(1,3,1,1), "lines"))