dplyr引用外部数据框索引赋值时出现结果异常问题排查
问题原因
- 该错误由R的向量索引规则与
ifelse的向量化执行逻辑共同导致:findInterval返回的limit_index包含值为0的结果,对应x小于limit$interval最小值1的情况ifelse执行时会先完整计算两个分支的所有内容,而非只计算符合条件的位置:limit$target[limit_index]会对全部100个limit_index同时做索引,而R中向量索引为0时会直接丢弃对应位置的元素,最终得到的limit$target[limit_index]长度小于100- R会自动对短向量做循环补齐来匹配
ifelse要求的长度,最终导致target值和原行位置完全错位,因此会出现limit_index为1却返回3.5的异常结果
修复方案
方案1:调整索引避免0值(推荐)
提前给limit$target补充一个占位值对应index=0的场景,避免索引时丢失元素:
require(dplyr) require(tibble) set.seed(123) x <- runif(100, -2, 10) limit <- data.frame(interval = 1:4, target = 1:4 + 0.5) # 给target前补一位占位值,对应index=0的位置 limit$target <- c(NA, limit$target) limit_index <- findInterval(x, limit$interval) df <- data.frame(x = x, limit_index = limit_index) df_target <- df %>% mutate(target = ifelse(limit_index == 0, x, limit$target[limit_index]))
方案2:先初始化再替换
先把target默认赋值为x,再单独替换符合条件的行,避免0索引参与计算:
require(dplyr) require(tibble) set.seed(123) x <- runif(100, -2, 10) limit <- data.frame(interval = 1:4, target = 1:4 + 0.5) limit_index <- findInterval(x, limit$interval) df <- data.frame(x = x, limit_index = limit_index) df_target <- df %>% mutate(target = x) %>% mutate(target = replace(target, limit_index > 0, limit$target[limit_index[limit_index > 0]]))
内容的提问来源于stack exchange,提问作者sedsiv
相关产品推荐
相关产品推荐

