`combine_vars()` 中的错误:!至少一层必须包含所有分面变量:在 facet_wrap() & facet_grid() 函数中

Error in `combine_vars()`: ! At least one layer must contain all faceting variables: in function with facet_wrap() & facet_grid()

我正在尝试在 R 上创建一个函数,它在我的 wd 上创建并保存一个带有小平面的点图。以下函数的代码:

get_dotplot <- function(df, xvalue, avgvalue, sdvalue, svalue, gvalue, main, xaxis, yaxis, glegend, figure_title)
{
  dp <- ggplot(df, aes(x = xvalue, y = avgvalue, color = gvalue)) + 
    
    geom_point(stat = 'identity', aes(shape=svalue, color=gvalue))+
    
    geom_errorbar(aes(ymin=avgvalue-sdvalue, ymax=avgvalue+sdvalue))+
    
            facet_grid(cols = vars(svalue), scales = "fixed")+

        labs(x = xaxis, y = yaxis, title = main, color=glegend)+
 
        theme(axis.title.x.bottom = element_text(hjust = 0.5, vjust = 1),
              axis.title.y = element_text(hjust = 0.5, vjust = 1),
 
              axis.ticks.x = element_line(),
              axis.text.x = element_text(angle = 0, hjust = 1, vjust = 0.5, size = 7),
axis.ticks.x.bottom = element_line(colour = "grey", size = (0.5)),
axis.ticks.y.left = element_line(colour = "black", size = (0.4)),

panel.background=element_rect(colour = "black", size = 0.5, fill=NA),
panel.grid = element_blank())

    print(dp)
    ggsave(paste(figure_title, "png", sep = "."), plot = dp, scale = 1, dpi = 600)
}

get_dotplot(df, xvalue, avgvalue, sdvalue, svalue, gvalue, main, xaxis, yaxis, glegend, figure_title)

但是,我总是收到此错误消息:

Error in `combine_vars()`:
! At least one layer must contain all faceting variables: `svalue`.
* Plot is missing `svalue`
* Layer 1 is missing `svalue`
* Layer 2 is missing `svalue`
Backtrace:
  1. global get_dotplot_errorbar_yaxis(...)
  3. ggplot2:::print.ggplot(dp)
  5. ggplot2:::ggplot_build.ggplot(x)
  6. layout$setup(data, plot$data, plot$plot_env)
  7. ggplot2 f(..., self = self)
  8. self$facet$compute_layout(data, self$facet_params)
  9. ggplot2 f(...)
 10. ggplot2::combine_vars(data, params$plot_env, cols, drop = params$drop)

我怀疑这是因为分面的原因,所以我在 facet_wrap() 和 facet_grid() 之间试了试,但没有结果。有人可以帮我吗? 我检查了一下,我的数据框中有 svalue 变量,它拼写正确。我也参考了以前关于该主题的问题,但它们没有帮助。

数据集看起来像这样,但是有更多的个体和天数:

set.seed(108)
n <- 1:12
treatment <- factor(paste("trt", 1:2))
individuals <- sample(LETTERS, 2)
days <- c("12", "20", "25")
avg_var1 <- sample(1:100, 12) 
sd_var1 <- sample(1:50, 12) 
avg_var2 <- sample(1:100, 12) 
sd_var2 <- sample(1:50, 12) 
avg_var3 <- sample(1:100, 12) 
sd_var3 <- sample(1:50, 12)
test <- data.frame(n, treatment, individuals, days,avg_var1, sd_var1, avg_var2, sd_var2, avg_var3, sd_var3)

我在 R 上定义函数的变量如下:

df=test
xvalue=test$days
avgvalue=test$avg_var1
sdvalue = test$sd_var1
svalue=test$treatment
gvalue=test$individuals
main= "var1 in function of days"
xaxis="days"
yaxis="var1"
glegend="individuals"
figure_title ="var1_days"

如所写,您的代码将列传递到函数中,重复数据框中的数据。这似乎与 ggplot 中使用的 non-standard 评估“表现不佳”。本质上 ggplot 正在寻找 df 中名为“svalue”的列以用于分面(它没有找到)。修复此问题后,错误栏会出现同样的问题。

一种解决方法是只传递列名,并使用 aes_string 作为变量。这不适用于分面或计算值,因此这些值是在函数开始时计算的。这将给出:

get_dotplot <- function(df, xvalue, avgvalue, sdvalue, svalue, gvalue, main, xaxis, yaxis, glegend, figure_title)
{
  df$ymin <- df[[avgvalue]] - df[[sdvalue]]
  df$ymax <- df[[avgvalue]] + df[[sdvalue]]
  df$facets <- df[[svalue]]
  
  dp <- ggplot(df, aes_string(x = xvalue, y = avgvalue, color = gvalue)) + 
    
    geom_point(stat = 'identity', aes_string(shape=svalue, color=gvalue)) +
    
    geom_errorbar(aes(ymin=ymin, ymax=ymax))+
    
    facet_grid(cols = vars(facets), scales = "fixed")+
    
    labs(x = xaxis, y = yaxis, title = main, color=glegend)+
    
    theme(axis.title.x.bottom = element_text(hjust = 0.5, vjust = 1),
          axis.title.y = element_text(hjust = 0.5, vjust = 1),
          
          axis.ticks.x = element_line(),
          axis.text.x = element_text(angle = 0, hjust = 1, vjust = 0.5, size = 7),
          axis.ticks.x.bottom = element_line(colour = "grey", size = (0.5)),
          axis.ticks.y.left = element_line(colour = "black", size = (0.4)),
          
          panel.background=element_rect(colour = "black", size = 0.5, fill=NA),
          panel.grid = element_blank())
  
  print(dp)
  ggsave(paste(figure_title, "png", sep = "."), plot = dp, scale = 1, dpi = 600)
}

get_dotplot(df=test,
            xvalue="days",
            avgvalue="avg_var1",
            sdvalue = "sd_var1",
            svalue="treatment",
            gvalue="individuals",
            main= "var1 in function of days",
            xaxis="days",
            yaxis="var1",
            glegend="individuals",
            figure_title ="var1_days")