寻求data.table解决方案:筛选满足V1/list.value≤0.8的最小list.value
Data.table 解决方案:筛选满足条件的最小list.value值
需求:为data.table中每行的V1值,找出满足V1/list.value ≤ 0.8条件的最小list.value值。
示例数据
library(data.table) list.value <- c(3.6, 3.0, 2.4, 1.8, 1.2, 0.6) dt <- as.data.table(seq(from = 0.5, to = 1.0, by = 0.1)) # 原示例中生成的比率列仅作参考,实际不需要提前生成 dt[, `:=`(ratio3.6 = V1 / 3.6) ][, `:=`(ratio3.0 = V1 / 3.0) ][, `:=`(ratio2.4 = V1 / 2.4) ][, `:=`(ratio1.8 = V1 / 1.8) ][, `:=`(ratio1.2 = V1 / 1.2) ][, `:=`(ratio0.6 = V1 / 0.6)]
输出如下:
> dt V1 ratio3.6 ratio3.0 ratio2.4 ratio1.8 ratio1.2 ratio0.6 1: 0.5 0.1388889 0.1666667 0.2083333 0.2777778 0.4166667 0.8333333 2: 0.6 0.1666667 0.2000000 0.2500000 0.3333333 0.5000000 1.0000000 3: 0.7 0.1944444 0.2333333 0.2916667 0.3888889 0.5833333 1.1666667 4: 0.8 0.2222222 0.2666667 0.3333333 0.4444444 0.6666667 1.3333333 5: 0.9 0.2500000 0.3000000 0.3750000 0.5000000 0.7500000 1.5000000 6: 1.0 0.2777778 0.3333333 0.4166667 0.5555556 0.8333333 1.6666667
预期结果
新增一列后的输出:
V1 min_val 1: 0.5 1.2 2: 0.6 1.2 3: 0.7 1.2 4: 0.8 1.2 5: 0.9 1.2 6: 1.0 1.8
原尝试代码问题
原代码逻辑错误:
copy(dt)[, test := which.min((V1 / list.value) <= 0.8)][]
which.min会将逻辑向量(TRUE/FALSE)转换为数值1/0,返回的是第一个0(即不满足条件的元素)的位置,而非满足条件的最小list.value的位置。
可行解决方案
# 按行处理,筛选满足条件的list.value并取最小值 dt[, min_val := { # 转换条件:V1/x ≤0.8 等价于 x ≥ V1/0.8(x为正数,不等号方向不变) eligible_vals <- list.value[list.value >= V1 / 0.8] min(eligible_vals) }, by = V1] # 查看结果 dt[, .(V1, min_val)]
逻辑说明
- 条件转换:将
V1/list.value ≤0.8转换为list.value ≥ V1/0.8,避免除法运算的逻辑混淆; - 筛选符合条件的
list.value元素; - 取筛选结果中的最小值,即为满足要求的最小
list.value。
内容的提问来源于stack exchange,提问作者Howard
相关产品推荐
相关产品推荐

