如何根据另一DataFrame的区间列匹配数值并添加对应乘数?
解决方案:给dfA匹配对应区间的乘数
我来帮你搞定这个问题!你之前的代码没法批量处理整个DataFrame的原因是,subset会把dfA$Value和dfB的所有行做广播比较,返回的是所有满足条件的dfB行,而不是每个Value对应的单个乘数。下面给你几个实用的解决方法:
方法1:用dplyr的case_when(直观易读)
如果你的区间是固定不变的,直接用case_when逐个定义区间对应的乘数就很方便:
library(dplyr) # 加载你的数据 dfA <- structure(list(User = 1:5, Value = c(54L, 12L, 7L, 123L, 74L)), row.names = c(NA, -5L), class = "data.frame") dfB <- structure(list(Min = c(0L, 50L, 80L, 100L, 120L), Max = c(50L, 80L, 100L, 120L, 1000L), Mult = c(0, 0.5, 0.8, 1, 1.2)), class = "data.frame", row.names = c(NA, -5L)) # 添加Mult列 dfA <- dfA %>% mutate(Mult = case_when( Value > 0 & Value < 50 ~ 0, Value >= 50 & Value < 80 ~ 0.5, Value >= 80 & Value < 100 ~ 0.8, Value >= 100 & Value < 120 ~ 1, Value >= 120 ~ 1.2 )) # 查看结果 dfA
运行后就能得到你想要的结果:
User Value Mult 1 1 54 0.5 2 2 12 0.0 3 3 7 0.0 4 4 123 1.2 5 5 74 0.5
方法2:用cut函数(适合动态区间)
如果dfB的区间可能会变化,用cut函数自动匹配区间更灵活,不需要手动修改条件:
# 提取区间断点和对应乘数 breaks <- c(dfB$Min, max(dfB$Max)) labels <- dfB$Mult # 给Value分区间并匹配乘数 dfA$Mult <- cut(dfA$Value, breaks = breaks, labels = labels, include.lowest = TRUE, right = FALSE) # 把因子转换成数值型 dfA$Mult <- as.numeric(as.character(dfA$Mult))
这里right = FALSE表示区间是左闭右开(比如[0,50)),正好符合你Value > Min & Value < Max的条件;include.lowest = TRUE确保最小的数值也能被正确匹配。
方法3:用fuzzyjoin做模糊匹配(最灵活)
如果你的区间规则经常变动,推荐用fuzzyjoin包的模糊匹配功能,自动找到每个Value对应的区间:
library(fuzzyjoin) dfA <- fuzzy_left_join(dfA, dfB, by = c("Value" = "Min", "Value" = "Max"), match_fun = list(`>`, `<`)) %>% select(User, Value, Mult)
这个方法会自动为每个Value找到Min < Value < Max的对应行,然后保留你需要的列,完全不用手动写区间条件,非常适合动态数据。
为什么你之前的代码无效?
你之前的subset(dfB, dfA$Value > dfB$Min & dfA$Value < dfB$Max)会把dfA$Value的5个值和dfB的5行做广播比较,生成一个5×5的逻辑矩阵,subset会返回所有满足任意一个条件的dfB行,而不是每个Value对应的单个行,所以没法正确赋值给dfA$Mult。
内容的提问来源于stack exchange,提问作者PietroAiorta
相关产品推荐
相关产品推荐

