如何编写R函数,根据DataFrame中能量值范围获取对应积分
问题描述
现有如下R数据:
library(tidyverse) table <- tibble( points = 0:10, energy = c(0, 120, 240, 300, 380, 500, 600, 780, NA, NA, NA), cost = c(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) )
需要编写一个函数,接收数值型的energy_input参数,根据输入值所在区间返回对应的points值。当前仅实现了精确匹配逻辑:
energy_points <- function(energy_input) { table %>% filter(energy == energy_input) %>% pull(points) }
期望的区间匹配规则及示例如下:
| energy_input | points |
|---|---|
| 50 | 0 |
| 120 | 0 |
| 121 | 1 |
| 240 | 1 |
| 241 | 2 |
核心规则:
- 输入值≤120 →返回0分
- 120<输入值≤240 →返回1分
- 240<输入值≤300 →返回2分,以此类推
- 输入值>780 →返回7分
解决方案
可以利用R内置的findInterval()函数实现高效的区间匹配,同时保证代码灵活性(后续阈值变化时无需修改函数逻辑)。
完整函数代码
energy_points <- function(energy_input) { # 过滤energy列的NA值,确保数据按energy递增排序 valid_table <- table %>% drop_na(energy) %>% arrange(energy) # 提取区间分界点(去掉第一个0,取后续的energy值作为区间上限) breaks <- valid_table$energy[-1] # 提取对应的points值向量 point_vec <- valid_table$points # 用findInterval匹配区间,调整索引后返回对应points idx <- findInterval(energy_input, breaks, left.open = TRUE) + 1 point_vec[idx] }
代码逻辑说明
- 数据预处理:先过滤掉
energy列的NA值,确保数据按energy从小到大排序,避免因顺序问题导致区间判断错误。 - 区间分界点设置:取
valid_table中除第一个值(0)外的所有energy值作为区间上限,对应规则中的120、240、300...780。 - 区间匹配:
findInterval(energy_input, breaks, left.open = TRUE)会返回输入值所在区间的索引:- 输入值≤120 →返回0
- 120<输入值≤240 →返回1
- ...
- 输入值>780 →返回7
- 给返回的索引加1,刚好对应
point_vec中对应的points值位置。
测试验证
运行以下代码验证结果符合预期:
energy_points(50) # 返回0 energy_points(120) # 返回0 energy_points(121) # 返回1 energy_points(240) # 返回1 energy_points(241) # 返回2 energy_points(780) # 返回6 energy_points(800) # 返回7
内容的提问来源于stack exchange,提问作者Jay Bee
相关产品推荐
相关产品推荐

