如何用两个不同的因素对图进行分面包装

How to facet wrap plots with two different factors

例如,我有两个试验,每个试验都有年份和治疗的主要因素。 我想绘制对同一图的响应,最好是试验 1/治疗/年,试验 2 也是如此。 我能得到的最接近的显示在简单的示例图片上。基本上我得到两个连接在一起的图表,一个显示试验 1 和试验 2 中的治疗效果,y 轴代表内容,另一个显示试验 1 和试验 2 中年份的效果,y 轴代表相同的内容。

Simple example of plot with Si content affected by treatments and year of sampling

是否可以将图形分面包装在一起,或者至少删除多余的 y 轴?

我使用的代码是:

a <- ggplot(I1, aes(x=fct_reorder(SISTEM, ORDER), y=Si)) + geom_jitter(show.legend=FALSE, width=0.25, color="black", size=0.5) + stat_summary(fun.data = mean_cl_normal, show.legend=FALSE, color="red", size=0.3) + labs(x=NULL,
   y="Si (mg / 100 g)") + facet_wrap(~POSKUS, ncol=2, scales="free_x") + theme_classic(base_family = "Palatino Linotype") + theme(axis.text=element_text(colour="black", size=8), axis.title=element_text(colour="black", size=8), axis.text.x=element_text(angle=45, vjust = 1, hjust=1)) + theme(strip.background = element_blank()) + ggplot(I1, aes(x=Leto, y=Si)) + geom_jitter(show.legend=FALSE, width=0.25, color="black", size=0.5) + scale_x_continuous(breaks=c(2016,2017)) + stat_summary(fun.data = mean_cl_normal, show.legend=FALSE, color="red", size=0.3) + labs(x=NULL,
   y="") + facet_wrap(~POSKUS + Leto, ncol=4, scales="free_x") + theme_classic(base_family = "Palatino Linotype") + theme(axis.text=element_text(colour="black", size=8), axis.title=element_text(colour="black", size=8), axis.text.x=element_text(angle=45, vjust = 1, hjust=1)) +  theme(strip.background = element_blank())`

下面给出的解决方案在某种程度上可以工作,但仍需要进行一些小的调整。 使用提供的代码,并将其扩展以根据需要对处理进行排序,并更改构面包装中变量的顺序,提供如图 2 所示的图。但是,构面标签现在仅显示 1 和 2,而不是试验 1 和试验 2。此外,是否有可能只有一个试验 1 和试验 2 名称用于 TREATMENT 和 YEAR 变量?

添加输出:

I2 <- structure(list(Leto = c("2016", "2016", "2016", "2016", "2016", 
"2016", "2016", "2016", "2016", "2016", "2016", "2016", "2016", 
"2016", "2016", "2017", "2017", "2017", "2017", "2017", "2017", 
"2017", "2017", "2017", "2017", "2017", "2017", "2017", "2017", 
"2017", "2016", "2016", "2016", "2016", "2016", "2016", "2016", 
"2016", "2016", "2016"), POSKUS = structure(c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L), .Label = c("Trial 1", "Trial 2"), class = "factor"), 
    SISTEM = structure(c(5L, 5L, 5L, 1L, 1L, 1L, 2L, 2L, 2L, 
    3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 1L, 1L, 1L, 2L, 2L, 2L, 
    3L, 3L, 3L, 4L, 4L, 4L, 6L, 6L, 6L, 7L, 7L, 7L, 8L, 8L, 8L, 
    9L), .Label = c("Manure-N0", "Manure-N1", "Manure-N2", "Manure-N3", 
    "No.org-N0", "No.org-N3", "Straw-N0", "Straw-N1", "Straw-N2", 
    "Straw-N3"), class = "factor"), ORDER = c(1, 1, 1, 2, 2, 
    2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 1, 1, 1, 2, 2, 2, 3, 3, 3, 
    4, 4, 4, 5, 5, 5, 5, 5, 5, 1, 1, 1, 2, 2, 2, 3), DUSIK = c(0, 
    0, 0, 0, 0, 0, 55, 55, 55, 110, 110, 110, 165, 165, 165, 
    0, 0, 0, 0, 0, 0, 55, 55, 55, 110, 110, 110, 165, 165, 165, 
    165, 165, 165, 0, 0, 0, 55, 55, 55, 110), Si = c(9.35, 11.6, 
    9.71, 8.96, 6.13, 7.08, 3.74, 3.72, 4.75, 1.3, 1.82, 3.41, 
    5.13, 3.41, 3.68, 7.67, 7.48, 6.21, 5.02, 9.46, 7.79, 8.11, 
    3.59, 8.28, 7.36, 9.69, 9.08, 6.46, 5.48, 7.9, 5.27, 4.06, 
    4.22, 5.6, 5.92, 6.9, 3.26, 4.45, 3.09, 4.38), P = c(2.62, 
    2.26, 2.33, 2.57, 3.06, 2.99, 1.71, 2.06, 2.18, 1.48, 1.71, 
    2.66, 2.24, 2.38, 2.55, 2.49, 2.48, 3.9, 2.65, 1.79, 2.88, 
    2.54, 3.22, 2.54, 2.88, 2.93, 3.26, 2.09, 3.03, 2.56, 2.43, 
    2.72, 2.59, 2.58, 3.71, 2.5, 2.45, 2.48, 3.49, 3.31), S = c(1.24, 
    0.95, 1.07, 1.17, 1.15, 1.15, 0.81, 1.08, 1.07, 0.89, 0.85, 
    1.15, 1.12, 1.22, 1.24, 1.16, 0.98, 1.32, 1.29, 1.04, 1, 
    0.9, 1.19, 1.03, 1.14, 1.05, 1.14, 1.1, 1.13, 1.25, 0.92, 
    1.19, 0.84, 1.27, 1.14, 1.05, 1.29, 1.05, 1.15, 1.02), Cl = c(0.39, 
    0.31, 0.32, 0.3, 0.39, 0.38, 0.24, 0.26, 0.32, 0.35, 0.3, 
    0.31, 0.3, 0.32, 0.28, 0.3, 0.24, 0.27, 0.29, 0.28, 0.25, 
    0.34, 0.38, 0.34, 0.33, 0.31, 0.33, 0.33, 0.31, 0.35, 0.25, 
    0.25, 0.26, 0.35, 0.35, 0.39, 0.33, 0.25, 0.25, 0.28), K = c(4.47, 
    4.05, 3.59, 4.18, 4.07, 4.43, 3.12, 3.79, 4.63, 5.02, 4.52, 
    4.49, 4.64, 4.21, 4.38, 4.27, 4.08, 5.23, 3.66, 3.39, 4.14, 
    3.99, 4.21, 3.83, 4.19, 4.95, 5.11, 3.44, 4.27, 4.6, 4.99, 
    4.54, 4.12, 3.82, 5.55, 4.48, 3.7, 3.8, 5.08, 4.47), Ca = c(0.78, 
    0.68, 0.66, 0.69, 0.77, 0.73, 0.46, 0.6, 0.66, 0.59, 0.61, 
    0.71, 0.77, 0.58, 0.7, 0.61, 0.79, 0.87, 0.77, 0.69, 0.84, 
    0.62, 0.77, 0.62, 0.66, 0.71, 0.68, 0.59, 0.67, 0.73, 0.62, 
    0.69, 0.61, 0.69, 0.8, 0.72, 0.56, 0.6, 0.63, 0.65), Ti = c(78.5, 
    73.7, 74, 69, 68.9, 52.3, 33.7, 35, 26.6, 41, 50.7, 42.2, 
    33.6, 38.7, 41.5, 56.9, 64.6, 60.1, 69.4, 65.7, 65.7, 52.6, 
    42.2, 46.1, 50.8, 44.1, 35.6, 47.3, 39.2, 47.7, 39.6, 40.3, 
    38.2, 67.9, 52.3, 63.1, 43.4, 35.1, 37.2, 27), Fe = c(56.2, 
    52.9, 57.1, 48.8, 46.7, 35.1, 45.8, 48.6, 49.6, 71.5, 66, 
    85.7, 45.6, 70.2, 58.8, 75.6, 85.2, 93.9, 85.7, 68.7, 70.1, 
    61.2, 60.6, 76.8, 113, 68.5, 74.9, 91.9, 44.4, 104, 62.1, 
    55.3, 78.5, 75.7, 51.7, 53.2, 49, 74.4, 51.9, 57.6), Zn = c(31.3, 
    29.9, 28, 27.4, 27.9, 27.7, 19.6, 19.6, 22, 20.6, 23.1, 20.6, 
    25.1, 22.6, 22.7, 32.5, 35.5, 31.1, 28.6, 29.2, 29.6, 21.8, 
    29.5, 25, 26.1, 24.7, 20.1, 23.9, 20.3, 24.6, 20.3, 21.1, 
    26.6, 27.4, 32.6, 30.4, 19.9, 21.8, 24.7, 20.7), Br = c(8.54, 
    7.65, 6.27, 5.83, 7.25, 6.92, 4.74, 4.79, 4.51, 7.53, 5.02, 
    4.35, 3.98, 3.64, 4.26, 10, 13.7, 12.7, 7.67, 8.62, 10.1, 
    2.52, 3.63, 2.7, 2.44, 2.73, 2.49, 5.9, 2.52, 2.56, 6.05, 
    5.6, 6.98, 7.81, 12.3, 8.11, 5.91, 6.01, 6.15, 5.74), Rb = c(1.95, 
    1.53, 2.12, 1.44, 2.54, 1.84, 1.62, 2.78, 2.35, 3.24, 3.62, 
    3.48, 4.74, 3.34, 4.21, 5.43, 3.94, 5.55, 3.01, 2.19, 3.34, 
    3.55, 5.08, 2.63, 5.44, 4.67, 4.71, 6.52, 2.99, 3.24, 4.19, 
    3.11, 4.11, 1.57, 1.26, 1.14, 1.95, 2.21, 2.57, 2.41), Sr = c(0.94, 
    0.97, 0.86, 1.07, 1.19, 1.97, 1.08, 1.23, 1.35, 1.23, 1.17, 
    1.03, 0.86, 0.96, 0.86, 3.51, 1.94, 3.44, 1.47, 1.95, 2.14, 
    1.36, 4.22, 2.07, 1.92, 1.8, 2.34, 2.89, 2.13, 2.62, 1.3, 
    1.16, 1.95, 1, 1.41, 0.77, 1.25, 1.09, 1.37, 1.28), N = c(5.68, 
    4.93, 4.36, 6.36, 4.68, 5, 4.67, 3.38, 3.33, 3.94, 3.61, 
    3.52, 3.03, 2.74, 2.7, 8.47, 7.33, 5.82, 8.01, 7.34, 7.12, 
    5.84, 4.5, 4.17, 3.91, 3.57, 2.35, 3.44, 4.2, 1.94, 2.97, 
    3.1, 3.42, 5.04, 5.42, 7.35, 3.28, 3.55, 4.2, 3.79), C = c(-29.04, 
    -28.81, -29.12, -28.91, -29.07, -29.13, -29.16, -29.16, -28.98, 
    -28.81, -28.74, -28.56, -28.58, -28.33, -28.51, -29.49, -30.45, 
    -30.34, -29.91, -30.13, -30.86, -30.3, -30.23, -30.46, -29.69, 
    -29.43, -29.74, -29.75, -29.92, -29.52, -28.44, -28.24, -28.01, 
    -28.68, -28.77, -29.13, -29.13, -29.41, -29, -28.85)), row.names = c(NA, 
40L), class = "data.frame")

使用分面实现所需结果的一种方法是将数据框分成两部分,如下所示:

  1. 第一个数据框包含治疗数据,第二个数据框包含年份数据。
  2. 在这些数据框中的每一个中,将要在 x 轴上绘制的变量重命名为具有相同的名称(我选择了 ´x). Doing so allows use to have one x-axis for the two different variables. But make sure to convert year or ´Leto 作为字符。
  3. 为每个 data.frame 添加一个标识符,可用于分面(除了您的变量 POSKUS)。
  4. 将数据分成两个 df,我们需要两个 geom_jitter 和两个 stat_summary 层。
  5. 最后,我向 facet_wrap 添加了一个自定义标签函数,以仅在构面条文本中显示试用标签。
library(dplyr)
library(ggplot2)

d1 <- I2 %>% 
  select(x = SISTEM, Si, POSKUS) %>% 
  mutate(name = "SISTEM", name = factor(name, levels = c("SISTEM", "Leto")))

d2 <- I2 %>% 
  select(x = Leto, Si, POSKUS) %>% 
  mutate(name = "Leto", name = factor(name, levels = c("SISTEM", "Leto")))

base <- ggplot(mapping = aes(x = x, y = Si)) +
  geom_jitter(data = d1, show.legend = FALSE, width = 0.25, color = "black", size = 0.5) +
  stat_summary(data = d1, fun.data = mean_cl_normal, show.legend = FALSE, color = "red", size = 0.3) +
  geom_jitter(data = d2, show.legend = FALSE, width = 0.25, color = "black", size = 0.5) +
  stat_summary(data = d2, fun.data = mean_cl_normal, show.legend = FALSE, color = "red", size = 0.3) +
  labs(
    x = NULL,
    y = "Si (mg / 100 g)"
  ) +
  #theme_classic(base_family = "Palatino Linotype") +
  theme_classic() +
  theme(axis.text = element_text(colour = "black", size = 8), 
        axis.title = element_text(colour = "black", size = 8), 
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
  theme(strip.background = element_blank())

base +
  facet_wrap(~name+POSKUS, nrow = 1, scales = "free_x", labeller = function(d) list(as.character(d$POSKUS)))
#> Warning: Removed 1 rows containing missing values (geom_segment).

EDIT 要在更改变量顺序后为每个试验设置一个标签,您可以使用 ggh4x:: facet_nested_wrap:

base +
  ggh4x::facet_nested_wrap(~POSKUS+name, nrow = 1, scales = "free_x", labeller = function(d) list(as.character(d$POSKUS)))
#> Warning: Removed 1 rows containing missing values (geom_segment).