如何找出满足要求的数值组合:基于R语言土壤深度数据集计算c值总和
问题描述
按id分组,找出每组中所有土壤深度测量的可行组合,要求组合的总覆盖深度最多为30,且组合需完整覆盖从0到最大深度(不超过30)的区间、无重叠覆盖。最终输出每个有效组合对应的id、总覆盖深度(lowest_depth)以及该组合的c值总和(lowest_depth_c)。
输入数据集
input <- tribble(~id, ~soil_depth_min, ~soil_depth_max, ~c, 1, 0, 15, 10, 1, 0, 7.5, 8, 1, 7.5, 15, 3, 1, 15, 30, 11, 2, 0, 15, 25, 2, 15, 30, 7, 3, 0, 20, 16)
需求说明
id=2:仅有一种组合(0-15)+(15-30),对应c值总和25+7=32,总深度30。id=3:仅有一种组合(0-20),对应c值16,总深度20。id=1:存在两种有效组合:(0-15)+(15-30),c值总和10+11=21,总深度30;(0-7.5)+(7.5-15)+(15-30),c值总和8+3+11=22,总深度30。
预期输出:
output <- tribble(~id, ~lowest_depth, ~lowest_depth_c, 1, 30, 21, 1, 30, 22, 2, 30, 32, 3, 20, 16)
尝试的错误代码及输出
用户尝试了以下代码,但未区分不重叠的有效组合,导致结果错误:
input %>% mutate(soil_depth = paste0(soil_depth_min,"-",soil_depth_max)) %>% group_by(id) %>% summarise(lowest_depth = -sum(-soil_depth_max[soil_depth_max<=30], soil_depth_min[soil_depth_max<=30]), lowest_depth_c = sum(c[soil_depth_max<=30]))
错误输出:
id lowest_depth lowest_depth_c <dbl> <dbl> <dbl> 1 1 45 32 2 2 30 32 3 3 20 16
解决方案
核心逻辑是枚举每组的所有测量项组合,筛选出无重叠、从0开始且总深度≤30的有效组合:
library(dplyr) library(purrr) # 定义函数:找出单个id下的所有有效组合 find_valid_combinations <- function(df) { items <- df %>% select(soil_depth_min, soil_depth_max, c) n <- nrow(items) # 生成所有非空组合 all_combinations <- map(1:n, function(k) combn(1:n, k, simplify = FALSE)) %>% unlist(recursive = FALSE) # 筛选符合条件的组合 valid_combinations <- keep(all_combinations, function(idx) { subset <- items[idx,] %>% arrange(soil_depth_min) # 检查是否从0开始 if (first(subset$soil_depth_min) != 0) return(FALSE) # 检查区间是否连续无重叠 for (i in 2:nrow(subset)) { if (subset$soil_depth_min[i] != subset$soil_depth_max[i-1]) return(FALSE) } # 检查总深度不超过30 last(subset$soil_depth_max) <= 30 }) # 计算每个有效组合的结果 map_dfr(valid_combinations, function(idx) { subset <- items[idx,] tibble( lowest_depth = max(subset$soil_depth_max), lowest_depth_c = sum(subset$c) ) }) %>% distinct() } # 分组处理并生成最终结果 input %>% group_by(id) %>% group_modify(~find_valid_combinations(.x)) %>% ungroup() %>% arrange(id, lowest_depth_c)
输出结果
# A tibble: 4 × 3 id lowest_depth lowest_depth_c <dbl> <dbl> <dbl> 1 1 30 21 2 1 30 22 3 2 30 32 4 3 20 16
代码说明
find_valid_combinations函数:针对单个id的数据集,生成所有测量项组合,筛选出满足从0开始、区间连续无重叠、总深度≤30的有效组合。- 使用
group_modify按id分组处理每个子集,最终整理输出符合预期的结果。
内容的提问来源于stack exchange,提问作者frandude
相关产品推荐
相关产品推荐

