创建自定义 ggplot 函数并动态设置 y 轴的限制

create custom ggplot function and set limit for y axis dynamically

我正在尝试创建一个如下所示的自定义 ggplot 函数,并通过向下面的第一个函数添加第四个参数来设法完成我需要的操作。

第一个函数可以灵活地将参数 limit_for_y_axis 设置为我想要的任何值;但是,我想知道如何通过将第四个参数 (limit_for_y_axis) 设置为 [=26= 的最大值来使其动态化]

# data
dt <- data.frame(month = as.Date(c("2018-03-01", "2018-02-01", "2018-01-01")), n = c(3000,2000,1000))

# version 1 (works fine)
horizontal_bar_chart_1 <- function(data, var_x, var_y, limit_for_y_axis){
  ggplot(data, aes_q(x=substitute(var_x), y=substitute(var_y))) +
    geom_bar(stat = "identity") +
    coord_flip() +
    geom_text(aes_q(label = substitute(var_y)), hjust = -.3, color = "gray35") +
    scale_y_continuous(expand = c(0, 0),
                       limits = c(0, max(limit_for_y_axis) * 1.3)
                       )

}

# test of horizontal_bar_chart_1 
horizontal_bar_chart_1(data = dt, var_x = month, var_y = n, limit_for_y_axis = dt$n)

# version 2 (doesn't work)
horizontal_bar_chart_2 <- function(data, var_x, var_y){
  limit_for_y_axis = max(data$var_y) * 1.3
  ggplot(data, aes_q(x=substitute(var_x), y=substitute(var_y))) +
    geom_bar(stat = "identity") +
    coord_flip() +
    geom_text(aes_q(label = substitute(var_y)), hjust = -.3, color = "gray35") +
    scale_y_continuous(expand = c(0, 0),
                       limits = c(0, limit_for_y_axis)
    )

}

# test of horizontal_bar_chart_2
horizontal_bar_chart_2(data = dt, var_x = month, var_y = n)

第二个函数给出以下错误信息:

Error in if (zero_range(as.numeric(limits))) { :    
missing value where TRUE/FALSE needed 
In addition: Warning messages: 
1: In max(data$var_y) : no non-missing arguments to max; returning -Inf 
2: Removed 3 rows containing missing values (position_stack).

您不能使用字符串变量来使用 $ 对数据帧进行切片,这是您隐式尝试使用 max(data$var_y) 进行的操作。它不是查找具有您传递给 var_y 的字符串名称的列,而是查找字面上名为 "var_y"

的列

max(data$var_y) 替换为 max(data[,var_y]),它应该可以工作。

编辑

我要解决这个问题的方法是将所有内容明确地设为字符串并使用 aes_string 来定义带有字符串的 ggplot 美学。函数调用中的 var_x = month, var_y = n 等结构很危险,因为如果您创建名为 monthn 的变量并且您想使用它们来引用数据框列,它们会改变行为。完整的解决方案如下所示:

horizontal_bar_chart_2 <- function(data, var_x, var_y){
  limit_for_y_axis = max(data[,var_y]) * 1.3
  ggplot(data, aes_string(x=var_x, y=var_y)) +
    geom_bar(stat = "identity") +
    coord_flip() +
    geom_text(aes_string(label=var_y), hjust = -.3, color = "gray35") +
    scale_y_continuous(expand = c(0, 0),
                       limits = c(0, limit_for_y_axis)
    )

}

# test of horizontal_bar_chart_2
horizontal_bar_chart_2(data = dt, var_x = "month", var_y = "n")