使用dplyr比较R数据框两列表型列的差异结果异常问题
R语言dplyr计算两列表列逐行差集问题解决方案
问题原因
- 运算逻辑错误:你使用的
group_by(seqs)+mutate的写法不会触发逐行计算,setdiff默认将两个列表列整体作为输入计算差集,而非逐行配对计算两个向量的差集。 - 字符串匹配误差:拆分字符串后部分位点前后带有多余空格,例如
" N:G204R"和"N:G204R"会被判定为不同字符串,导致差集计算结果偏差。
修正代码
library(dplyr) # v1.0.7及以上版本适用 seqs <- c("seq1","seq2","seq3","seq4","seq5") expect_mut <- c("S:T20N,S:D614G","S:T20N,S:D614G","S:T20N,N:G204R,N:G80R", "N:G204R, S:D614G", "N:G204R, S:D614G") observed_mut <- c("S:T20N","S:D164G","S:T20N, N:G204R","S:D614G,N:G204R","S:D164G,S:T19I") data_frame <- data.frame(seqs, expect_mut, observed_mut) data_frame <- data_frame %>% mutate( # 拆分字符串同时去除每个元素的前后空格 expect_mut = lapply(strsplit(as.character(expect_mut), ","), trimws), observed_mut = lapply(strsplit(as.character(observed_mut), ","), trimws) ) %>% # 声明逐行运算 rowwise() %>% # 计算差集后用list包裹,保证输出为列表列 mutate(diff_mut = list(setdiff(observed_mut, expect_mut))) %>% # 可选:取消行分组,不影响后续运算 ungroup()
代码说明
- 新增
trimws处理清除拆分后字符串的多余空格,保证相同位点字符串匹配一致。 - 使用
rowwise()声明逐行运算逻辑,每一行单独计算两个向量的差集。 setdiff返回的向量用list()包裹,确保输出为列表列格式,符合原有数据结构要求。
如果你不想用rowwise语法,也可以用基础函数mapply实现逐行配对计算,写法如下:
data_frame <- data_frame %>% mutate( expect_mut = lapply(strsplit(as.character(expect_mut), ","), trimws), observed_mut = lapply(strsplit(as.character(observed_mut), ","), trimws), diff_mut = mapply(setdiff, observed_mut, expect_mut, SIMPLIFY = FALSE) )
两种写法最终输出的结果完全一致,均符合预期要求。
内容的提问来源于stack exchange,提问作者heuristic
相关产品推荐
相关产品推荐

