感谢任何可以帮助我解决这个问题的人。几天来,我一直试图弄清楚这一点,但没有运气。如果有解决方案,我深表歉意,但广泛的网络搜索没有帮助。
所以我有两个数据集 df 和 df2,df1 是我的数据集,其中有伪重复项(如果我只考虑某些变量则为重复项),df2 是我的查找表。
df <- data.frame(
x = c("green", "green", "blue", "orange", "orange"),
y = c("W12", "W12", "W12", "W11", "W12"),
z = c(23, 54, 21, 16, 54)
)
df2 <- data.frame(y=c("W12","W11"), z=c(54, 16))
所以,我们有:
> df
x y z
1 green W12 23
2 green W12 54
3 blue W12 21
4 orange W11 16
5 orange W12 54
> df2
y z
1 W12 54
2 W11 16
我正在寻找一种方法,不仅可以根据 (x,y) 剔除其中一个重复项,还可以根据查找表中 z 的值告诉 R 保留哪些重复项。所以在这里,保留记录 #2 但不是基于它在数据集中的位置(在我的真实日期中,z 的值有时大而其他时间小,具体取决于 y)。
我试过使用 !replicate() 但找不到指向引用表的方法,只能保留第一条记录(或最后一条记录)。
df_dup<-df[c("x", "y")]
df[!duplicated(df_dup),]
我也尝试过类似的方法
ddply(df,c("x", "y"),
function(v) {
if (nrow(v)>1) v[which(c(df$y, df$z) %in% c(df2$y, df2$z)), ]
if (nrow(v)==1) v
}
)
df %>%
group_by(x,y) %>%
filter(c(df$y,df$z) %in% c(df2$y,df2$z))
但是这里发生了一些奇怪的事情,%in% 并不完全匹配这些对,而是匹配 (y,z) 的任意组合。
我希望的输出是
df
x y z
2 green W12 54
3 blue W12 21
4 orange W11 16
5 orange W12 54
但是选择第 2 行不是因为它是最后一行,而是因为它与查找表匹配。在我较长的数据集中,要保留的行最终可能是第一行或第二行。
再次提前感谢任何能在 R 中找到方法执行此操作的人。最终,我将需要在一个巨大的数据集上执行此操作,并将多个变量作为分组变量,其中只有一个变量是查找的一部分表。
最佳答案
我可能会...
library(data.table)
setDT(df); setDT(df2)
ord = +is.na(df2[df, on=c("y", "z"), which=TRUE])
unique(df[ order(ord) ], by=c("x","y"))
x y z
1: green W12 54
2: orange W11 16
3: orange W12 54
4: blue W12 21
这会优先考虑在 df2
中匹配的行;但是如果你想做相反的事情(就像在问题的早期版本中那样),只需在 ord
的定义中放置一个 -
而不是 +
。
工作原理:
X[Y, on, which=TRUE]
为 Y
的每一行返回 X
的行匹配。如果有多个匹配项,则全部返回(但在您的查找表中,没有理由重复)。如果没有匹配项,则返回缺失值。
+is.na(w)
其中 w
是一个行号向量,返回一个我们可以排序的向量:
1
如果w
是缺失值0
否则
unique(Y[order(ord)], by)
按我们的向量对 Y
进行排序,然后像往常一样删除重复项,保留每组的第一个观察值。对于此步骤,您也可以选择执行 Y[order(ord), .SD[1L], by]
。
关于r - 根据 R 中的查找表保留特定的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39667837/