【问题标题】:Conditionally remove duplicate elements from a data.table有条件地从 data.table 中删除重复元素
【发布时间】:2014-05-12 06:12:15
【问题描述】:

我已经合并了两个数据集。集合 X 包含一个 ID 和一个 startDate,集合 Y 一个 ID 和一个 endDate。两者都以 ID 作为密钥。我想将每个 startDate 与其对应的 endDate 匹配(前提是它大于 startDate)。问题是 ID 可能在给定集合中出现多次,但在同一集合中并不总是出现多次。因此,startDate 可以与 endDate 的多个条目匹配,反之亦然。这基本上是我的代码:

require(data.table)

startDate = c(1,2,3,1)
IDX = c(1,2,2,3)
endDate = c(2,3,4)
IDY = c(1,1,2)

X = data.table(startDate,IDX)
Y= data.table(endDate,IDY)

setkey(X,IDX)
setkey(Y,IDY)
DT = X[Y,allow.cartesian = TRUE][endDate>startDate]   

现在我想有条件地从集合 DT 中删除重复的条目。对应于键“ID”和“startDate”,我只想保留具有最低 endDate 的重复条目。对于“ID”和“endDate”的每个重复条目,我想做同样的事情,但保留具有最高 startDate 的条目。

DT 看起来像这样:

   IDX startDate endDate
1:   1         1       2
2:   1         1       3
3:   2         2       4
4:   2         3       4

此新数据表中有两个重复项。 1 和 2 是彼此的副本,具有不同的 endDate。只有条目 1 必须保留(因为它的 endDate 与 startDate 最接近)。 3 和 4 也是彼此的副本,具有不同的 startDate。在这里,条目 4 必须保留(因为它具有关闭 startDate 到 endDate)。所以需要的输出是

   IDX startDate endDate
1:   1         1       2
2:   2         3       4

我不知道如何使用duplicated(DT) 来实现这一点,因为它不一定给出我想要的特定副本。有人有建议吗?此外,我是否可以在“加入”期间解决这个问题,而不是事后解决?

【问题讨论】:

  • 我不确定我是否正确理解了您的问题:data.table( IDX = c(1,1,1), startDate = c(2,2,1), endDate = c(1,2,2) ) 的正确结果是什么?
  • @Arun 这是涵盖我想要的所有情况的最简单示例。我更新了输出。

标签: r merge data.table conditional-statements duplicate-removal


【解决方案1】:

我认为这不能在单个连接中完成,但也许以下方法可以工作:

Y[, startDate := endDate]
setkey(X, IDX, startDate)
setkey(Y, IDY, startDate)

Y[X, roll = -Inf][, list(startDate = startDate[.N]), by = list(IDY, endDate)]
#   IDY endDate startDate
#1:   1       2         1
#2:   2       4         3

【讨论】:

  • 我现在显示预期的输出,以便问题更清楚(我希望)。实际上,X 和 Y 的尺寸并不相等,顺便说一句。
  • @Forzaa 好的,看看编辑后的版本是不是你要找的
  • +1 roll 的使用很棒。您可能需要添加 nomatch=0L 以确保在特定 ID 没有 endDate > startDate 时没有 NA 结果。
  • @Arun 谢谢,这是一个很好的观点 - OP 可以决定他们在这种情况下更喜欢做什么
  • @eddi,是的,对于 OP 来说,这一点或多或少是 :)。很好的答案,再一次!我认为它也相当于Y[X[J(unique(IDX)), mult="last"], roll=-Inf](或从1.9.3+ 也等于Y[unique(X, by="IDX", fromLast=TRUE), roll=-Inf]
猜你喜欢
  • 2018-08-08
  • 2018-08-12
  • 2014-05-04
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
相关资源
最近更新 更多