从DataFrame筛选子集未得到预期结果的问题排查
问题根源:浮点数精度误差导致精确匹配失败
你遇到的问题几乎可以肯定是浮点数的精度问题——虽然你肉眼看df2里的t2数值和df1的t1完全一致,但计算机存储浮点数时的二进制精度限制,会让这些数值实际存在微小的差异,导致%in%的精确匹配漏掉了大量本该匹配的记录。
你可以随便挑一个df2里的t2值,运行下面的代码验证这个猜测:
# 取df2的第一个时间值,检查是否在df1的t1里精确存在 any(df1$t1 == df2$t2[1])
大概率会返回FALSE,哪怕两个数值看起来完全一样。
解决方案:改用近似匹配
下面给你两种实用的解决方法,能保证拿到完整的114条匹配结果:
方法一:用dplyr的closest关联(推荐,代码简洁)
如果你使用dplyr包(版本1.1.0及以上),可以用join_by(closest())实现“找最接近时间点”的匹配,直接关联两个数据集:
library(dplyr) # 为每个t2匹配df1中最接近的t1对应的data1,保留df2全部114条记录 df_new <- df2 %>% left_join(df1, by = join_by(closest(t2 == t1)))
方法二:基础R实现(无需额外包)
如果你不想依赖dplyr,可以用基础R的sapply结合which.min手动找到每个t2对应的最接近t1的索引:
# 遍历df2的每个t2,找到df1中t1与它差值最小的位置 match_indices <- sapply(df2$t2, function(t_val) { which.min(abs(df1$t1 - t_val)) }) # 构建包含匹配结果的新数据集 df_new <- data.frame( t2 = df2$t2, data1 = df1$data1[match_indices], data2 = df2$data2 )
额外提醒
如果你的业务场景允许一定的误差范围(比如允许t1和t2的差值小于1e-6),也可以用逐行筛选的方式实现:
df_new <- df2 %>% rowwise() %>% mutate(data1 = df1$data1[which.min(abs(df1$t1 - t2))]) %>% ungroup()
本质和上面的方法逻辑一致,只是写法稍有不同。
内容的提问来源于stack exchange,提问作者ACE
相关产品推荐
相关产品推荐

