在dplyr中如何实现条件mutate操作同时保持原有数值不变
你需要的功能可以通过dplyr::mutate()结合if_else()实现,核心逻辑是先筛选出需要重编码的行,对这些行的score做反向转换,其余行保留原值即可。
你提到的重编码规则本质是1-5分的反向计分,可以直接用6 - score实现,不用逐个匹配数值,效率更高。
完整实现代码
library(tidyverse) # 构造示例数据 tb1 <- tibble(ID = c(1,2,3,4,5), Quest_MF_1_1 = c(1,2,2,1,2), Quest_MF_1_2 = c(1,2,2,1,2), Quest_MF_2_1 = c(2,3,3,2,1), Quest_MF_2_2 = c(1,3,4,1,2), Quest_MV_1_1 = c(1,2,4,1,2), Quest_MV_1_2 = c(1,2,2,1,2), Quest_MV_2_1 = c(2,3,5,2,2), Quest_MV_2_2 = c(1,3,4,1,2)) # 长表转换,注意原代码cols参数范围有误,tb1共9列,要转的是2~9列 tb_long <- tb1 %>% pivot_longer( cols = 2:9, names_to = c("Questionnaire", "Question", "Timepoint"), names_pattern = "Quest_(.*)_(.*)_(.*)", values_to = "score" ) # 执行重编码 tb_result <- tb_long %>% mutate( score = if_else( # 匹配需要重编码的题组:MF下的第2题、MV下的第1题 (Questionnaire == "MF" & Question == "2") | (Questionnaire == "MV" & Question == "1"), 6 - score, # 符合条件的执行反向计分 score # 不符合条件的保留原分数 ) )
批量处理大量题目的优化方案
如果你实际数据中需要反向计分的题目较多,可以单独维护一个反向计分题目的匹配表,避免写冗长的判断条件,示例如下:
# 维护需要反向计分的<问卷,题目>组合 reverse_key <- tibble( Questionnaire = c("MF", "MV"), # 填入所有需要反向的问卷编码 Question = c("2", "1"), # 对应填入需要反向的题目编号 reverse_flag = TRUE ) # 用左连匹配判断是否需要反向,自动完成重编码 tb_result <- tb_long %>% left_join(reverse_key, by = c("Questionnaire", "Question")) %>% mutate( reverse_flag = replace_na(reverse_flag, FALSE), score = if_else(reverse_flag, 6 - score, score) ) %>% select(-reverse_flag) # 用完删除标记列即可
内容的提问来源于stack exchange,提问作者Anneke
相关产品推荐
相关产品推荐

