You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:45:03