基于Conflict列条件复制数据的R代码优化请求
优化方案
核心思路是利用Conflict列的命名规律动态匹配df2中的对应列,避免为每个Conflict值重复编写代码,完美适配数百种不同取值的场景。
优化后代码
library(dplyr) library(tidyr) # 原始数据 df <- data.frame(study_id=c("1", "1", "4", "4", "5"), Conflict=c("WATER.START", "WATER.STOP", "OIL.START", "NA", "WATER.STOP"), Result=c("TRUE", "TRUE", "TRUE", "NA", "TRUE"), stringsAsFactors = FALSE) df2 <- data.frame(study_id=c("1", "2", "3", "4", "5"), WATER.start=c(1, 1, 2, NA, 6), WATER.truestart=c(1, 1, 2, NA, 25), WATER.stop=c(33, 3, 2, NA, 8), WATER.truestop= c(34, 4, 2, NA, 8), stringsAsFactors = FALSE) # 核心处理流程 final_result <- df %>% # 过滤有效行:Result为TRUE且Conflict不是NA filter(Result == "TRUE" & Conflict != "NA") %>% # 连接df2数据 left_join(df2, by = "study_id") %>% # 拆分Conflict为类型和动作,动作转小写 separate(Conflict, into = c("type", "action"), sep = "\\.", remove = FALSE) %>% mutate(action = tolower(action)) %>% # 动态提取initial和verification列的值 rowwise() %>% mutate( initial = pull(cur_data(), paste0(type, ".", action)), verification = pull(cur_data(), paste0(type, ".true", action)) ) %>% ungroup() %>% # 保留目标列 select(study_id, Conflict, initial, verification) print(final_result)
代码说明
- 过滤与连接:先筛选有效行再连接数据,减少后续处理的数据量。
- 拆分Conflict:通过
separate把WATER.START拆成type=WATER和action=START,转小写后可直接拼接成df2中的列名(比如WATER.start)。 - 动态取值:用
rowwise()结合pull()和字符串拼接,根据每行的type和action动态提取对应列的值,不管有多少种Conflict取值都能自动适配。 - 整理输出:最后只保留需要的4列,得到目标结果。
运行结果
study_id Conflict initial verification 1 1 WATER.START 1 1 2 1 WATER.STOP 33 34 3 5 WATER.STOP 8 8
内容的提问来源于stack exchange,提问作者GJW
相关产品推荐
相关产品推荐

