R自定义函数报错:'x'必须为数值型但变量本身已是数值型
自定义分位数函数报错:'x' must be numeric 的原因与解决
问题场景
原本直接使用dplyr::mutate创建百分位数分组变量的代码可以正常运行:
base_conjunta <- base_conjunta %>% mutate(centils100_total_canvi = cut(total_canvi, unique(quantile(total_canvi, seq(0, 1, 0.01))), labels = FALSE))
但将逻辑封装为自定义函数后:
centils100 <-function(data,x) { x <- enquo(x) data %>% mutate(x = cut(x, unique(x, seq(0, 1, 0.01))), labels = FALSE,.names = "centils100_{col}") }
调用函数时传入字符串变量名:
base_conjunta <- centils100(base_conjunta, "total_canvi")
出现错误:
Error in `mutate()`: i In argument: `across(...)`. Caused by error in `cut.default()`: ! 'x' must be numeric Backtrace: 1. global centils101(base_conjunta, "total_canvi") 13. base::cut.default(x, unique(x, seq(0, 1, 0.01))) 14. base::stop("'x' must be numeric")
已知total_canvi本身是数值型变量,单独使用mutate无报错。
错误原因分析
参数传递不匹配:
函数中使用enquo(x)捕获变量,但调用时传入的是字符串"total_canvi"。enquo的作用是捕获裸变量名(不带引号的变量),而非字符串,这导致x被解析为字符串表达式,而非数据框中的数值列,因此cut函数判定输入非数值。分位数计算逻辑错误:
原正常代码用quantile(total_canvi, seq(0,1,0.01))计算分位数,但函数中错误写成unique(x, seq(0,1,0.01))——不仅把quantile误写为unique,还颠倒了参数顺序,既无法生成正确的分位数断点,又进一步导致cut输入异常。mutate语法错误:- 直接赋值
x = cut(...)会覆盖函数参数x,而非在数据框中创建新列; .names参数的使用方式错误,需结合:=动态赋值语法才能生成带变量名的新列。
- 直接赋值
修正后的函数
版本1:支持裸变量名调用
centils100 <- function(data, x) { x <- enquo(x) # 获取变量名用于新列命名 col_label <- as_label(x) data %>% mutate( # 动态命名新列,引用捕获的变量 "centils100_{col_label}" := cut( !!x, unique(quantile(!!x, seq(0, 1, 0.01))), labels = FALSE ) ) } # 调用时使用裸变量名 base_conjunta <- centils100(base_conjunta, total_canvi)
版本2:支持字符串变量名调用
centils100 <- function(data, x) { # 将字符串转换为符号,用于引用数据框列 x_sym <- sym(x) data %>% mutate( "centils100_{x}" := cut( !!x_sym, unique(quantile(!!x_sym, seq(0, 1, 0.01))), labels = FALSE ) ) } # 调用时传入字符串变量名 base_conjunta <- centils100(base_conjunta, "total_canvi")
内容的提问来源于stack exchange,提问作者FrancoBattiato
相关产品推荐
相关产品推荐

