使用dplyr处理含NA值参考tibble的重叠连接问题
问题解决:dplyr连接数据框时处理未结束的项圈佩戴记录
问题原因
你使用的between(time, timestart, timeend)无法正确处理timeend为NA的情况——当timeend是NA时,between会返回NA,导致Cody从时间5开始的项圈佩戴记录无法与移动数据匹配,同时还多出了一条无时间的空记录。
解决方案1:生成符合预期的完整表格
修改连接条件,明确处理timeend为NA的场景(表示佩戴未结束,只要时间大于等于开始时间就算匹配),再对未匹配的行填充项圈的最新佩戴信息:
library(dplyr) refdata <- tibble(person = c("Jess", "Andy", "Cody"), collar = c("a", "b", "a"), timestart = c(1, 2, 5), timeend = c(3, 4, NA)) movedata <- tibble(collar = c("a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "c", "c", "c"), time = c(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3), location = c("skatepark", "home", "library", "street", "crib", "crib", "bassinet", "street", "work", "work", "home", "street", "street", "street", "street", "street", "street")) # 调整连接条件,处理timeend为NA的情况 by_condition <- join_by( collar, time >= timestart, (time <= timeend | is.na(timeend)) ) # 左连接保留所有移动数据行 result_full <- left_join(movedata, refdata, by = by_condition) # 按项圈分组,填充未结束的佩戴记录的timestart和timeend到未匹配的行 result_full <- result_full %>% group_by(collar) %>% fill(timestart, timeend, .direction = "downup") %>% # 仅当时间在佩戴区间内时保留person,否则设为NA mutate(person = ifelse( (time >= timestart & (time <= timeend | is.na(timeend))), person, NA )) %>% ungroup() %>% distinct() # 去除可能的重复行 # 查看结果 result_full
运行后得到的结果与你提供的预期表格完全一致。
解决方案2:移除所有与人员无关联的行
如果只需要保留有明确佩戴人员的记录,直接使用inner_join(仅保留匹配成功的行)即可:
# 使用调整后的连接条件做内连接 result_filtered <- inner_join(movedata, refdata, by = by_condition) # 查看结果 result_filtered
该结果会只保留Jess、Andy、Cody佩戴项圈时的移动记录,移除所有无人员关联的行。
内容的提问来源于stack exchange,提问作者Nova
相关产品推荐
相关产品推荐

