r - ggplot2 函数 - 检查用户输入变量是否应该是映射的美学

标签 r ggplot2 nse

我编写了一个函数来制作散点图,该函数允许用户将点的大小输入为数值(保留在 aes() 调用之外)或作为要映射的数据帧中的变量(需要进入 aes() 调用内部)。我远不是 NSE 方面的专家,尽管我已经让它发挥作用,但我觉得必须有更好的方法来做到这一点?

该函数的简化版本如下:

library(tidyverse)

data <- tibble(x = 1:10, y = 1:10)

test_func <- function(data, variable = 6){
  # capture the variable in vars (I think quote would also work in this function)
  variable <- vars({{variable}})
  
  # convert it to a string and check if the string starts with a digit
  # i.e. checking if this is a simple point size declaration not an aes mapping
  is_number <- variable[[1]] %>% 
    rlang::as_label() %>% 
    str_detect("^[:digit:]*$")
  
  # make initial ggplot object
  p <- ggplot(data, aes(x = x, y = y))
  
  # if variable is a simple number, add geom_point with no aes mapping
  if(is_number){
    variable <- variable[[1]] %>% 
      rlang::as_label() %>% 
      as.numeric()
    
    p <- p + geom_point(size = variable)
  } else{
    # otherwise it must be intended as an aes mapping variable  
    variable <- variable[[1]] %>% 
      rlang::as_label()
    
    p <- p + geom_point(aes(size = .data[[variable]]))
  }
  p
}

# works as a number
test_func(data, 10)

# works as a variable
test_func(data, y)

reprex package于2021年4月8日创建(v2.0.0)

最佳答案

一个选项是检查用户提供给变量的内容是否是数据中的列。如果是,请在 aes() 映射中使用该列。如果不是,则评估变量并将结果提供给 aes() 之外的 size:

test_func <- function(data, variable = 6) {
  v <- enquo(variable)
  gg <- ggplot(data, aes(x=x, y=y))
  
  if(exists(rlang::quo_text(v), data))
    gg + geom_point(aes(size=!!v))
  else
    gg + geom_point(size = rlang::eval_tidy(v))
}

# All of these work as expected:
test_func(data)      # Small points
test_func(data, 10)  # Bigger points
test_func(data, x)   # Using column x

作为奖励,此解决方案允许您传递存储在变量中的值,而不是直接数字输入。只要变量名称不在 data 中,它就会被正确计算并馈送到 size=:

z <- 20
test_func(data, z)   # Works

关于r - ggplot2 函数 - 检查用户输入变量是否应该是映射的美学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67007646/

相关文章:

r - 将数据框和列表连接到包含列表列的数据框中

r - 如何将变量传递到 R markdown .Rmd 文件中?

r - 如何在 R knitr 中包装一个非常长的段落 R 输出

r - R中的 Tornado /双面水平条形图,图表轴在给定值处交叉(而不是在零处交叉)

r - 如何根据 ggplot 散点图中最佳因子列绘制值列的两个子集?

r - 用 r 抓取 ajax 站点

r - 估计ggplot2中图例占用的绘图百分比

r - 函数 : nested conditions 中的 dplyr NSE 模式

r - R 中的 rlang 中的 expr 和 exprs 类是不同的!为什么?

r - ggplot 函数内 aes(...) 中变量的范围