我想从我的数据集中识别并删除重复项。问题是我有两个不同的标准。首先,我使用的主要标准是最近的时间。但是,并非所有重复项都有日期。对于缺少日期的案件,我将不得不一一检查,看看我要保留哪一行。所以,这就是我需要的:
假设我有以下数据:
df <- data.frame(id = c("a", "a", "b","b", "c","c"),
date = c("2023-05-16", "2023-08-21", "2023-06-05", NA, "2023-05-07", "2023-05-20"))
library(lubridate)
df$date <- ymd(df$date)
class(df$date)
[1] "Date"
df
id date
1 a 2023-05-16
2 a 2023-08-21
3 b 2023-06-05
4 b <NA>
5 c 2023-05-07
6 c 2023-05-20
首先,我需要识别包含 NA 的所有重复项以比较行并查看我将保留哪一行。我需要一个与此类似的结果数据框,它包含重复值和唯一值:
id date
1 b 2023-06-05
2 b <NA>
请注意,我有两行,以便我可以比较它们。我保持示例简单,但我不确定在我的实际数据框中每个 id 有多少个重复项。接下来,我将留下剩余的数据框:
id date
1 a 2023-05-16
2 a 2023-08-21
3 c 2023-05-07
4 c 2023-05-20
我只需要保留最新的值,我将以这样的方式结束:
id date
1 a 2023-08-21
2 c 2023-05-20
如果有不清楚的地方并且您需要更多说明,请告诉我。
我会使用标志而不是分割。使用
ave
您可以标记哪个 id 在日期中具有 anyNA
,创建一个 keep
向量来对有效或无效的进行子集化。使用 which.max
获取最新日期。
> df <- transform(df, flag=ave(as.integer(date), id, FUN=anyNA))
> keep <- !df$flag == 1
> by(df[keep, ], df[keep, ]$id, \(x) x[which.max(x$date), ]) |> do.call(what='rbind')
id date flag
a a 2023-08-21 0
c c 2023-05-20 0
> df[!keep, ]
id date flag
3 b 2023-06-05 1
4 b <NA> 1
数据:
> dput(df)
structure(list(id = c("a", "a", "b", "b", "c", "c"), date = structure(c(19493,
19590, 19513, NA, 19484, 19497), class = "Date"), flag = c(0L,
0L, 1L, 1L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-6L))