我有一个这样的数据框:
X Y Z T
1 2 4 2
3 2 1 4
7 5 NA 3
经过几个步骤(哪个不重要)我得到了这个df:
X Y Z T
1 2 4 2
3 2 NA 4
7 5 NA 3
我想获得一个新的数据框,仅由在这些步骤中没有改变的行组成;结果将是这个:
X Y Z T
1 2 4 2
7 5 NA 3
我该怎么办?
我有一个这样的数据框:
X Y Z T
1 2 4 2
3 2 1 4
7 5 NA 3
经过几个步骤(哪个不重要)我得到了这个df:
X Y Z T
1 2 4 2
3 2 NA 4
7 5 NA 3
我想获得一个新的数据框,仅由在这些步骤中没有改变的行组成;结果将是这个:
X Y Z T
1 2 4 2
7 5 NA 3
我该怎么办?
一个选项是base R
将paste
每个数据集的行放在一起并比较 ( ==
) 以创建一个逻辑向量,我们将其用于对新数据集进行子集化
dfO[do.call(paste, dfO) == do.call(paste, df),]
# X Y Z T
#1 1 2 4 2
#3 7 5 NA 3
其中“dfO”是旧数据集,“df”是新数据集
您可以使用 dplyr 的intersect
功能:
library(dplyr)
intersect(d1, d2)
# X Y Z T
#1 1 2 4 2
#2 7 5 NA 3
这是基本 Rintersect
函数的 data.frame 等效项。
如果您正在使用data.table
s,该软件包还提供了这样的功能:
library(data.table)
setDT(d1)
setDT(d2)
fintersect(d1, d2)
# X Y Z T
#1: 1 2 4 2
#2: 7 5 NA 3
恐怕既不是,semi join
也不是正确答案。并且不会正确处理重复的行。semi join 将改变行的顺序。intersect
merge
merge
intersect
从这个角度来看,我认为到目前为止唯一正确的是akrun的。
您还可以执行以下操作:
df1[rowSums(((df1 == df2) | (is.na(df1) & is.na(df2))), na.rm = T) == ncol(df1),]
但我认为 akrun 的方式更优雅,并且在速度方面可能表现更好。
另一种dplyr
解决方案:semi_join
.
dt1 %>% semi_join(dt2, by = colnames(.))
X Y Z T
1 1 2 4 2
2 7 5 NA 3
数据
dt1 <- read.table(text = "X Y Z T
1 2 4 2
3 2 1 4
7 5 NA 3",
header = TRUE, stringsAsFactors = FALSE)
dt2 <- read.table(text = " X Y Z T
1 2 4 2
3 2 NA 4
7 5 NA 3",
header = TRUE, stringsAsFactors = FALSE)