根据 R 中的查找 table 保留特定的重复项
keep specific duplicate based on lookup table in R
感谢任何可以帮助我解决这个问题的人。几天来,我一直试图弄清楚这一点,但没有运气。如果有解决方案,我深表歉意,但广泛的网络搜索没有帮助。
所以我有两个数据集 df 和 df2,df1 是我的数据集,其中我有伪重复项(如果我只考虑某些变量则重复),df2 是我的查找 table。
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 保留哪个 table。所以在这里,保留记录 #2 但不是基于它在数据集中的位置(在我的真实日期中,z 的值有时大而其他时间小,具体取决于 y)。
我试过使用 !replicate() 但找不到指向引用 table 的方法,只能保留第一条记录(或最后一条).
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 行不是因为它是最后一行,而是因为它匹配查找 table。在我较长的数据集中,要保留的行最终可能是第一行或第二行。
再次提前感谢任何能在 R 中找到方法执行此操作的人。最终,我将需要在一个巨大的数据集上执行此操作,并将多个变量作为分组变量,其中只有一个是其中的一部分查找 table.
一种方法如下:
查找 df
中 x
和 y
的所有重复行。为此,我们使用 Sven Hohenstein's answer found here:
dup.ind <- which(duplicated(df[,c("x","y")]) | duplicated(df[,c("x","y")], fromLast = TRUE))
我们还想在 result
中保留所有其他行(没有重复的行),所以我们使用 setdiff
来识别那些:
other.ind <- setdiff(seq_len(nrow(df)), dup.ind)
从 dup.ind
只保留 df
中的 z
值等于 df2
中匹配 [=16] 的值=] 值。在这里,df2$z[match(df$y[dup.ind], df2$y)]
在 df2
中为每个 dup.ind
:
查找 z
值
keep.ind <- dup.ind[df$z[dup.ind] == df2$z[match(df$y[dup.ind], df2$y)]]
使用 c(keep.ind,other.ind)
对原始 df
进行子集化。在这里,我们sort
这些来保持原来的顺序(但那不是必须的):
result <- df[sort(c(keep.ind, other.ind)),]
使用您的输入数据,result
是:
print(result)
## x y z
##2 green W12 54
##3 blue W12 21
##4 orange W11 16
##5 orange W12 54
我可能会...
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]
returns,对于 Y
的每一行,匹配的 X
的行。如果有多个匹配项,则全部返回(但在您的查找 table 中,没有理由重复)。如果没有匹配项,则返回缺失值。
+is.na(w)
其中 w
是行号向量 returns 我们可以排序的向量:
1
如果 w
是缺失值
0
否则
unique(Y[order(ord)], by)
按我们的向量排序 Y
,然后像往常一样删除重复项,保留每组的第一个观察值。您可以交替执行此步骤 Y[order(ord), .SD[1L], by]
。
感谢任何可以帮助我解决这个问题的人。几天来,我一直试图弄清楚这一点,但没有运气。如果有解决方案,我深表歉意,但广泛的网络搜索没有帮助。
所以我有两个数据集 df 和 df2,df1 是我的数据集,其中我有伪重复项(如果我只考虑某些变量则重复),df2 是我的查找 table。
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 保留哪个 table。所以在这里,保留记录 #2 但不是基于它在数据集中的位置(在我的真实日期中,z 的值有时大而其他时间小,具体取决于 y)。
我试过使用 !replicate() 但找不到指向引用 table 的方法,只能保留第一条记录(或最后一条).
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 行不是因为它是最后一行,而是因为它匹配查找 table。在我较长的数据集中,要保留的行最终可能是第一行或第二行。
再次提前感谢任何能在 R 中找到方法执行此操作的人。最终,我将需要在一个巨大的数据集上执行此操作,并将多个变量作为分组变量,其中只有一个是其中的一部分查找 table.
一种方法如下:
查找
df
中x
和y
的所有重复行。为此,我们使用 Sven Hohenstein's answer found here:dup.ind <- which(duplicated(df[,c("x","y")]) | duplicated(df[,c("x","y")], fromLast = TRUE))
我们还想在
result
中保留所有其他行(没有重复的行),所以我们使用setdiff
来识别那些:other.ind <- setdiff(seq_len(nrow(df)), dup.ind)
从
查找dup.ind
只保留df
中的z
值等于df2
中匹配 [=16] 的值=] 值。在这里,df2$z[match(df$y[dup.ind], df2$y)]
在df2
中为每个dup.ind
:z
值keep.ind <- dup.ind[df$z[dup.ind] == df2$z[match(df$y[dup.ind], df2$y)]]
使用
c(keep.ind,other.ind)
对原始df
进行子集化。在这里,我们sort
这些来保持原来的顺序(但那不是必须的):result <- df[sort(c(keep.ind, other.ind)),]
使用您的输入数据,result
是:
print(result)
## x y z
##2 green W12 54
##3 blue W12 21
##4 orange W11 16
##5 orange W12 54
我可能会...
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]
returns,对于 Y
的每一行,匹配的 X
的行。如果有多个匹配项,则全部返回(但在您的查找 table 中,没有理由重复)。如果没有匹配项,则返回缺失值。
+is.na(w)
其中 w
是行号向量 returns 我们可以排序的向量:
1
如果w
是缺失值0
否则
unique(Y[order(ord)], by)
按我们的向量排序 Y
,然后像往常一样删除重复项,保留每组的第一个观察值。您可以交替执行此步骤 Y[order(ord), .SD[1L], by]
。