用tidyverse管道提取df1独有的去重Sample.ID时遇列选择错误
用tidyverse管道提取数据框独有的去重Sample.ID
需求
提取仅存在于df1中的Sample.ID,先去除重复值,要求用tidyverse的管道操作实现。
错误尝试及报错
尝试了以下两种写法均报错:
df1 %>% distinct(Sample.ID, .keep_all = TRUE) %>% df1$Sample.ID[!df1$Sample.ID %in% df2$Sample.ID]
df1 %>% distinct(Sample.ID, .keep_all = TRUE) %>% df1$Sample.ID[!df1$Sample.ID %in% df2$Sample.ID,]
错误信息:
Error in `[.data.frame`(., df1$Sample.ID, !df1$Sample.ID %in% df2$Sample.ID) : undefined columns selected
示例数据
df1 <- data.frame(Sample.ID=c("H22","H33","H44", "H55","H22","H33","H44", "H55"), sample.no=c(1,3,3,4,2,5,6,7)) df2 <- data.frame(Sample.ID=c("H33","H55"), pane=c(5,6))
(注:修正了原示例中df1最后一个H55缺失引号的问题,补充了sample.no的完整数据)
期望结果
Sample.ID 1 H22 2 H44
正确管道写法
方法1:distinct() + filter()
利用管道传递的当前数据框,直接针对Sample.ID列筛选:
df1 %>% distinct(Sample.ID) %>% # 去重,仅保留Sample.ID列 filter(!Sample.ID %in% df2$Sample.ID) # 筛选不在df2中的ID
方法2:distinct() + anti_join()(更符合tidyverse风格)
anti_join()专门用于筛选在第一个数据框中存在、但第二个数据框中不存在的行:
df1 %>% distinct(Sample.ID) %>% anti_join(df2, by = "Sample.ID")
错误原因说明
之前的写法错误在于:管道操作中%>%传递的是前一步处理后的数据框对象,而非原始的df1。直接在管道中使用df1$Sample.ID会绕过管道传递的数据,导致索引操作混乱,进而触发列未定义的错误。
内容的提问来源于stack exchange,提问作者Ana
相关产品推荐
相关产品推荐

