无法在R的dplyr中编写正确的异常值处理自定义函数
修正dplyr异常值处理函数的报错问题
问题描述
尝试用dplyr语法编写修正变量异常值的函数时运行报错,已写出可行的Base R版本,需修复dplyr版本的问题。
错误的dplyr函数代码
fn_outlier_fix <- function(x, df){ x = enquo(x) Q1 = df %>% pull(!!x) %>% quantile(0.25) %>% unname() Q3 = df %>% pull(!!x) %>% quantile(0.75) %>% unname() IQR = Q3 - Q1 UC = Q3 + (1.5 * IQR) LC = Q3 - (1.5 * IQR) df <- df %>% mutate(!!x := if_else(x > UC,UC,!!x), !!x := if_else(x < LC,LC,!!x)) }
测试数据与调用代码
library(dplyr) df_test <- tribble( ~sales, ~var1, ~var2, 22, 230.1, 37.8, 10, 44.5, 39.3, 9, 17.2, 45.9, 19, 151.5, 41.3, 13, 180.8, 10.8, 7, 8.7, 48.9, 12, 57.5, 32.8, 13, 120.2, 19.6, 5, 8.6, 2.1, 11, 199.8, 2.6)
调用代码:
fn_outlier_fix(x = var1, df = df_test)
报错信息
Error in
mutate():
! Problem while computingvar1 = if_else(x > UC, UC, var1).
Caused by error inif_else():
! Base operators are not defined for quosures. Do you need to unquote the quosure?Bad: myquosure > rhsGood: !!myquosure > rhsBacktrace:
- global fn_outlier_fix(x = var1, df = df_test)
- rlang:::Ops.quosure(x, UC)
可行的Base R版本函数
fn_outlier_fix <- function(x){ Q1 = quantile(x, 0.25) Q3 = quantile(x, 0.75) IQR = Q3 - Q1 UC = Q3 + (1.5 * IQR) LC = Q1 - (1.5 * IQR) x[x > UC] <- UC x[x < LC] <- LC x <- x }
修复后的dplyr函数及解释
修复后代码
fn_outlier_fix <- function(x, df){ x <- enquo(x) Q1 <- df %>% pull(!!x) %>% quantile(0.25) %>% unname() Q3 <- df %>% pull(!!x) %>% quantile(0.75) %>% unname() IQR_val <- Q3 - Q1 # 避免与内置函数IQR重名 UC <- Q3 + (1.5 * IQR_val) LC <- Q1 - (1.5 * IQR_val) # 修正原代码的下限计算错误 df %>% mutate(!!x := if_else(!!x > UC, UC, !!x), !!x := if_else(!!x < LC, LC, !!x)) }
关键修复点
- 解引用quosure对象:
if_else条件判断中必须用!!x替代x,x是quosure类型,无法直接参与比较,!!用于取出变量实际值。 - 修正异常值下限计算:原代码中
LC = Q3 - 1.5*IQR错误,正确逻辑是Q1 - 1.5*IQR,同步Base R版本的正确逻辑。 - 返回处理后的数据框:原代码未返回结果,修复后利用dplyr管道自动传递最后一步的处理结果。
- 避免变量名冲突:将
IQR改为IQR_val,防止与R内置的IQR()函数重名引发问题。
测试验证
fixed_df <- fn_outlier_fix(var1, df_test) print(fixed_df$var1)
输出结果中,超出上下限的异常值会被修正为对应临界值。
内容的提问来源于stack exchange,提问作者ViSa
相关产品推荐
相关产品推荐

