使用group_by() %>% group_modify()调用自定义异常值移除函数时的错误排查及tidyverse优化实现问询
问题分析与解决方案
你的错误根源在于自定义函数rm.outliers中列的提取方式。当使用group_modify时,传入函数的分组数据是tibble类型,而你用data[,c(column)]提取列时,返回的是一个单列tibble,而非原子向量。这会导致后续的逻辑筛选操作出现索引错误(错误信息里的“位置不存在”就是因为R把tibble当成了行索引来处理)。
修复自定义函数
只需要把函数中提取列的方式从data[,c(column)]改成data[[column]]([[会直接返回列对应的向量),修改后的函数如下:
rm.outliers <- function(data, column){ Q <- quantile(data[[column]], probs=c(.25, .75), na.rm = FALSE) iqr <- IQR(data[[column]]) up <- Q[2] + 1.5*iqr # Upper Range low <- Q[1] - 1.5*iqr # Lower Range data <- data[data[[column]] < up & data[[column]] > low, ] data }
现在再运行你原来的管道代码,就能正常工作了:
dataset <- dataset %>% group_by(patient_id, timepoint) %>% group_modify(~rm.outliers(.x,"Mean")) %>% ungroup()
更简洁的tidyverse实现方式
其实完全不需要自定义函数,直接用dplyr的filter结合between函数,在分组后直接完成异常值过滤,代码更简洁易读:
dataset_cleaned <- dataset %>% group_by(patient_id, timepoint) %>% filter(between(Mean, quantile(Mean, 0.25, na.rm = TRUE) - 1.5*IQR(Mean, na.rm = TRUE), quantile(Mean, 0.75, na.rm = TRUE) + 1.5*IQR(Mean, na.rm = TRUE))) %>% ungroup()
这里我额外加上了na.rm = TRUE,避免如果数据中有NA值时出现计算错误,你可以根据实际情况调整。
内容的提问来源于stack exchange,提问作者Cecilia López
相关产品推荐
相关产品推荐

