根据R中的查找表保留特定的副本

时间:2016-09-23 19:01:43

标签: r duplicates lookup

感谢任何可以帮助我的人。我已经试着在没有运气的情况下解决这几天了。我很抱歉,如果解决方案在那里,但广泛的网络搜索没有帮助。

所以我有两个数据集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

但是选择Row#2并不是因为它是最后一行,而是因为它匹配查找表。在我的较长数据集中,要保留的行可能最终成为第一个或第二个。

再次感谢能够在R中找到方法的人。最后,我需要在一个巨大的数据集上执行此操作,并将几个变量作为分组变量,其中只有一个是查找的一部分表

2 个答案:

答案 0 :(得分:2)

我可能会......

Module2

这会优先考虑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。< / p>

工作原理:

对于+的每一行,

X[Y, on, which=TRUE]会返回匹配的Y行。如果有多个匹配,则返回它们(但在查找表中,没有理由重复)。如果没有匹配项,则返回缺失值。

X其中+is.na(w)是行号的向量,返回一个我们可以按以下排序的向量:

  • w如果1是缺失值
  • w否则

0按照我们的向量对unique(Y[order(ord)], by)进行排序,然后像往常一样删除重复项,保持每组的第一次观察。您可以在此步骤中执行Y

答案 1 :(得分:0)

一种方法如下:

  1. x中查找ydf重复的所有行。为此,我们使用Sven Hohenstein's answer found here

    dup.ind <- which(duplicated(df[,c("x","y")]) | duplicated(df[,c("x","y")], fromLast = TRUE))
    
  2. 我们还想在result中保留所有其他行(没有重复项),因此我们使用setdiff来识别这些行:

    other.ind <- setdiff(seq_len(nrow(df)), dup.ind)
    
  3. dup.ind开始,仅保留zdf值等于df2中匹配y值的值。在此处,df2$z[match(df$y[dup.ind], df2$y)]为每个zdf2中查找dup.ind值:

    keep.ind <- dup.ind[df$z[dup.ind] == df2$z[match(df$y[dup.ind], df2$y)]]
    
  4. 使用df对原始c(keep.ind,other.ind)进行子集。在这里,我们sort这些来保持原始顺序(但这不是必需的):

    result <- df[sort(c(keep.ind, other.ind)),]
    
  5. 使用输入数据,result为:

    print(result)
    ##       x   y  z
    ##2  green W12 54
    ##3   blue W12 21
    ##4 orange W11 16
    ##5 orange W12 54