求助:如何用R语言实现基于数值大小的条件舍入
我来帮你搞定这个按阈值选择不同间隔舍入的问题!你的思路完全没问题,但R里的条件判断语法和Excel有差异,咱们一步步修正:
首先先说说你原来代码的几个小问题:
- 多个
if没有用else if衔接:R里如果写独立的if,会挨个判断,不仅逻辑容易出错(比如数值>10时会同时满足>1、>5的条件),还会直接报语法错误 sapply处理数据框后会返回矩阵,需要转回数据框格式才能保持原结构- 函数里用逗号分隔条件是不对的,必须用
else if来串联递进的条件
修正后的可行代码(基于plyr)
先把逻辑改成正确的链式条件判断,再处理数据框的数值列:
library(plyr) # 先定义一个按阈值舍入的函数 round_with_thresholds <- function(x) { if (x > 10) { round_any(x, 1) } else if (x > 5) { round_any(x, 0.5) } else if (x > 1) { round_any(x, 0.25) } else { x # 小于等于1的数值保持原样 } } # 把函数应用到数据框的所有数值列(非数值列保持不变) DataFrame <- as.data.frame(lapply(DataFrame, function(col) { if (is.numeric(col)) { sapply(col, round_with_thresholds) } else { col } }))
更简洁的tidyverse实现(推荐)
如果你愿意用dplyr(现在更常用的数据分析工具),可以用case_when让条件逻辑更清晰,同时批量处理数值列:
library(dplyr) library(plyr) # 还是需要round_any函数,或者自己实现 DataFrame <- DataFrame %>% mutate(across(where(is.numeric), ~ case_when( .x > 10 ~ round_any(.x, 1), .x > 5 ~ round_any(.x, 0.5), .x > 1 ~ round_any(.x, 0.25), TRUE ~ .x # 兜底:不满足前面条件的数值保持原样 )))
可选:自己实现round_any(不依赖plyr)
如果你不想依赖plyr包,可以自己写一个简单的舍入函数,效果和round_any一样:
my_round_any <- function(x, interval) { round(x / interval) * interval }
把上面代码里的round_any换成my_round_any就可以了。
内容的提问来源于stack exchange,提问作者nba2020
相关产品推荐
相关产品推荐

