基于双条件为R语言DataFrame的trial_number列填充参考值
R语言DataFrame区间匹配填充解决方案
问题描述
有两个独立的DataFrame:
- 主DataFrame:包含
start_time、end_time列,需填充trial_number列,行数较多 - 参考DataFrame:包含
reference_column(填充值)、a(区间左边界)、b(区间右边界)列,行数较少
需实现:仅当主DataFrame的start_time >= 参考DataFrame的a 且 end_time <= 参考DataFrame的b时,将对应reference_column格式化为两位数字(如1→01),填充到主DataFrame的trial_number列,每个参考区间对应主DataFrame的多行。
示例数据
参考DataFrame(ref_df)
ref_df <- data.frame( reference_column = c(1,2,3,4), a = c(10,22,30,45), b = c(20,24,40,55) )
主DataFrame(main_df)
main_df <- data.frame( start_time = c(12,22,23,31,35,36,37,46,47,50), end_time = c(18,23,24,32,36,37,39,51,53,54), trial_number = rep(NA, 10) )
解决方案
方法1:Base R 循环(适合新手理解)
直接遍历参考DataFrame的每个区间,匹配主DataFrame的行并填充:
# 初始化trial_number列 main_df$trial_number <- NA # 遍历参考DataFrame的每一行 for (i in 1:nrow(ref_df)) { # 筛选主DataFrame中满足当前区间条件的行索引 match_rows <- which(main_df$start_time >= ref_df$a[i] & main_df$end_time <= ref_df$b[i]) # 将参考值格式化为两位数字后填充 main_df$trial_number[match_rows] <- sprintf("%02d", ref_df$reference_column[i]) }
方法2:dplyr 管道式实现(更简洁高效)
利用dplyr的交叉连接和过滤功能,适合处理大数据量:
library(dplyr) # 先整理参考数据,生成格式化后的填充标签 ref_processed <- ref_df %>% mutate(trial_label = sprintf("%02d", reference_column)) # 交叉连接匹配条件,再合并回主DataFrame main_df <- main_df %>% cross_join(ref_processed) %>% filter(start_time >= a, end_time <= b) %>% select(start_time, end_time, trial_number = trial_label) %>% right_join(main_df, by = c("start_time", "end_time")) %>% select(names(main_df)) # 保持原列顺序
验证结果
运行上述代码后,主DataFrame的trial_number列会按要求填充,结果如下:
print(main_df) # start_time end_time trial_number # 1 12 18 01 # 2 22 23 02 # 3 23 24 02 # 4 31 32 03 # 5 35 36 03 # 6 36 37 03 # 7 37 39 03 # 8 46 51 04 # 9 47 53 04 # 10 50 54 04
内容的提问来源于stack exchange,提问作者sa-al
相关产品推荐
相关产品推荐

