从同样出现在另一个数据框

时间:2015-08-12 14:23:25

标签: r

我有两个数据框,df1包含许多值,df2包含一些也出现在df1中的值。 df2中的值是我要从df1中删除的值。

我试图通过合并来做到这一点,但似乎没有选择只保留两者中不存在的值。

我也尝试使用this answer中的代码来解决类似的问题。 这似乎有效,但它产生的数据帧的值比我预期的要少,即df1包含74911个值,df2包含767,删除后仍然有74064个 - 所以另外80个行是删除。我不确定为什么会这样,如果我能确定80行,或许我可以弄明白。

如果有人能想到实现目标的替代方法,我将非常感激!

以下是一些示例数据框,与实际数据框相比,它们非常简单:

chrom <- c(1, 2, 3, 4)
pos <- c(2, 7, 9, 14)
seq_c <- c('A', 'G', 'C', 'T')
seq_k <- c('G', 'C', 'A', 'C')
df1 <- data.frame(chrom, pos, seq_c, seq_k)

chrom <- c(1, 2)
pos <- c(2, 7)
seq_c <- c('A', 'G')
seq_k <- c('G', 'C')
df2 <- data.frame(chrom, pos, seq_c, seq_k)

预期的输出将是:

chrom <- c(3, 4)
pos <- c(9, 14)
seq_c <- c('C', 'T')
seq_k <- c('A', 'C')
df3 <- data.frame(chrom, pos, seq_c, seq_k)

3 个答案:

答案 0 :(得分:3)

我们可以使用anti_join中的dplyr来删除'df1'和'df2'之间常见的行,并且只保留其余行。

 library(dplyr)
 anti_join(df1, df2)

答案 1 :(得分:3)

以下是使用merge()然后从df1中删除与df2成功合并的所有行索引的想法:

df1[-merge(cbind(df1,ri=seq_len(nrow(df1))),df2)$ri,];
##   chrom pos seq_c seq_k
## 3     3   9     C     A
## 4     4  14     T     C

data.table有一个很好的方法:

library('data.table');
dt1 <- data.table(df1,key=names(df1));
dt2 <- data.table(df2,key=names(df2));
dt1[!dt2];
##    chrom pos seq_c seq_k
## 1:     3   9     C     A
## 2:     4  14     T     C

请注意,i [.data.table()参数中的感叹号在此处具有特殊含义; [.data.table()将其视为对dt2的联接的否定,而通常它会否定RHS数据的每个单元格。表。

答案 2 :(得分:3)

我使用stringAsFactors = FALSE重新创建了data.frame,在这种情况下,你只需使用dplyr中的setdiff:

chrom <- c(1, 2, 3, 4)
pos <- c(2, 7, 9, 14)
seq_c <- c('A', 'G', 'C', 'T')
seq_k <- c('G', 'C', 'A', 'C')
df1 <- data.frame(chrom, pos, seq_c, seq_k, stringsAsFactors = FALSE)

chrom <- c(1, 2)
pos <- c(2, 7)
seq_c <- c('A', 'G')
seq_k <- c('G', 'C')
df2 <- data.frame(chrom, pos, seq_c, seq_k, stringsAsFactors = FALSE)

library(dplyr)
df1 %>% setdiff(df2)