如何在R中按分组规则对数据表数值取整并替换小值
解决方案:处理data.table中指定列的数值格式化问题
问题原因
你的代码失败是因为case_when要求所有分支返回相同类型的数据,但你同时返回了数值(如round(.,1))和字符串(如<0.1),R无法自动统一类型,导致结果不符合预期或报错。核心解决思路是将所有处理后的结果转为字符类型,同时用格式化函数控制数值的显示格式。
方案一:使用dplyr语法(兼容data.table)
用across替代已弃用的mutate_at,并通过sprintf确保数值格式符合要求,同时统一返回字符类型:
library(dplyr) library(data.table) desired_solution <- exampledata %>% mutate(across(c(c, d), ~case_when( # 规则1:group>1000且数值>1 → 0位小数取整 group > 1000 & .x > 1 ~ sprintf("%.0f", round(.x, 0)), # 规则2:group>1000且0<数值<1 → 替换为"<1" group > 1000 & .x > 0 & .x < 1 ~ "<1", # 补充:group>1000且数值≤0 → 保留原数值(转字符) group > 1000 & .x <= 0 ~ as.character(.x), # 规则3:group<1000且数值>0.1 → 保留1位小数(含整数显示.0) group < 1000 & .x > 0.1 ~ sprintf("%.1f", round(.x, 1)), # 规则4:group<1000且数值<0.1 → 替换为"<0.1" group < 1000 & .x < 0.1 ~ "<0.1", # 处理其他边界情况(如等于0.1、等于1等) TRUE ~ as.character(.x) )))
方案二:使用data.table原生语法(推荐用于大型数据集)
data.table的原生操作效率更高,适合处理大型数据集,避免不必要的内存开销:
library(data.table) # 定义处理函数,封装所有规则 process_col <- function(x, group_col) { case_when( group_col > 1000 & x > 1 ~ sprintf("%.0f", round(x, 0)), group_col > 1000 & x > 0 & x < 1 ~ "<1", group_col > 1000 & x <= 0 ~ as.character(x), group_col < 1000 & x > 0.1 ~ sprintf("%.1f", round(x, 1)), group_col < 1000 & x < 0.1 ~ "<0.1", TRUE ~ as.character(x) ) } # 复制原数据避免修改原始数据,对c、d列应用处理函数 desired_solution <- copy(exampledata) desired_solution[, c("c", "d") := lapply(.SD, process_col, group_col = group), .SDcols = c("c", "d")]
验证结果
执行上述代码后,desired_solution将完全匹配你提供的期望结果,同时解决了类型冲突问题。
内容的提问来源于stack exchange,提问作者Eli
相关产品推荐
相关产品推荐

