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

时间:2018-03-23 19:35:35

标签: r function ggplot2 limit

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

第一个函数可以灵活地将参数 limit_for_y_axis 设置为我想要的任何值;但是,我想通过将第四个参数设置为 var_y 的最大值来了解如何使第四个参数( limit_for_y_axis )动态化。

# 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).

1 个答案:

答案 0 :(得分:3)

您不能使用字符串变量来切片$的数据帧,这是您隐含尝试使用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")