如何在R中基于标记校正数据框(交叉引用数据框)
嘿,我完全懂你现在的困境——想用Set B的数据去更新更长的Set A,但俩数据集的TS变量因为舍入问题有微小偏差,没法直接做精确匹配对吧?我给你几个实用的R方案,结合你给的示例数据来演示,你可以按需选:
首先先把你的示例数据和我构造的一个符合场景的Set B放出来(方便你测试):
library(tibble) # 你的Set A示例 setA <- tibble(TS = c(rep(2.0913, 4), rep(2.123, 5)), AF3_S = 1:9, AF4_S = 1:9) # 构造的Set B:TS有微小舍入偏差,条目数更少 setB <- tibble(TS = c(2.0912, 2.1231), AF3_New = c(100, 200), AF4_New = c(150, 250))
方案1:用
fuzzyjoin做模糊匹配(最直观) 这个包就是为非精确匹配设计的,你可以自定义TS的偏差容忍范围,比如允许±0.001的误差,匹配上之后再用Set B的值替换Set A的原有数据:
library(fuzzyjoin) library(dplyr) # 按TS的偏差范围匹配俩数据集 matched_data <- fuzzy_left_join( setA, setB, by = "TS", match_fun = function(x, y) abs(x - y) < 0.001 # 这里设定你的偏差容忍度 ) # 替换值:如果匹配到Set B的新值就用新的,没匹配到就保留原Set A的值 updated_setA <- matched_data %>% mutate( AF3_S = ifelse(!is.na(AF3_New), AF3_New, AF3_S), AF4_S = ifelse(!is.na(AF4_New), AF4_New, AF4_S) ) %>% select(TS = TS.x, AF3_S, AF4_S) # 保留原Set A的TS和更新后的列
方案2:用dplyr的
closest匹配(R 4.1+可用) 如果你的R版本是4.1及以上,dplyr自带的closest匹配超方便——不用手动设容忍度,它会自动给Set A的每个TS找Set B里最接近的那个值:
library(dplyr) updated_setA <- setA %>% left_join(setB, by = join_by(closest(TS))) %>% # 用coalesce函数自动取非空值:有新值就用新的,没有就留原来的 mutate( AF3_S = coalesce(AF3_New, AF3_S), AF4_S = coalesce(AF4_New, AF4_S) ) %>% select(-AF3_New, -AF4_New) # 删掉临时列
方案3:用data.table的滚动连接(大数据量首选)
如果你的数据集特别大,data.table的滚动连接效率会比dplyr高很多,同样可以设定偏差范围:
library(data.table) # 先转成data.table格式 setDT(setA) setDT(setB) # 滚动连接,允许TS的偏差在0.001以内 updated_setA <- setB[setA, on = .(TS), roll = 0.001, rollends = TRUE] %>% mutate( AF3_S = fifelse(!is.na(AF3_New), AF3_New, AF3_S), AF4_S = fifelse(!is.na(AF4_New), AF4_New, AF4_S) ) %>% select(TS, AF3_S, AF4_S)
几个要注意的小细节:
- 一定要先确认你的实际偏差范围,把容忍度设得比实际偏差稍大一点,但别太大,不然会出现错误匹配。
- 如果Set B里有多个TS都和Set A的某个TS在容忍范围内,上面的方案默认取第一个匹配项,你可以根据需求调整(比如取均值、取最后一个匹配项)。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

