You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用tidy eval与scales::rescale编写R语言自定义函数的问题

解决R语言tidy eval下scales::rescale的参数问题

你的核心问题是混淆了tidy eval中裸列名和字符串列名的处理逻辑:
{{col}}(curly-curly操作符)是用来捕获未加引号的裸列名(比如调用函数时写resc(df, val)),如果你的col参数是带引号的字符串(比如"mpg"),{{col}}会直接把它当成字符串字面量,而非引用数据框中的列,自然无法正确取值。

针对你需要接收带引号字符串参数的需求,有两种可行方案:

方案1:直接使用.data代词(最简洁)

保持参数为字符串格式,用.data[[col]]引用目标列,这是你最初可行代码的延伸写法:

library(dplyr)
library(scales)

resc <- function(df, col){
  df %>% 
    mutate(
      rescaled_value = scales::rescale(.data[[col]], to = c(0, 1), from = range(.data[[col]], na.rm = TRUE))
    )
}

注:给range()加上na.rm=TRUE可以避免数据含NA值时出错;另外scales::rescale默认from参数就是range(x, na.rm=TRUE),所以实际可以省略from参数,和你最初的正确代码效果完全一致。

方案2:兼容裸列名和字符串参数

如果想让函数同时支持两种调用方式(resc(df, "val")和resc(df, val)),可以用ensym()将输入转换为符号,再用!!解引用:

library(dplyr)
library(scales)

resc <- function(df, col){
  col_sym <- ensym(col)
  df %>% 
    mutate(
      rescaled_value = scales::rescale(!!col_sym, to = c(0, 1), from = range(!!col_sym, na.rm = TRUE))
    )
}

测试验证

# 生成测试数据
set.seed(123)
df <- data.frame(val = sample(1:10, 5, replace = TRUE))

# 调用函数(方案2支持两种写法)
resc(df, "val")
# 或 resc(df, val)

内容的提问来源于stack exchange,提问作者Lenn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:52:16