我有两个数据框,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)
答案 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)