根据条件删除大型数据集中的重复项

Delete duplicates in large dataset based on condition

我想根据条件删除非常大的数据集(数百万行)中的重复项。我考虑了以下简化示例来说明我的概率:

test <- read.table(
text = "
A   1900    1   10  45tz    tztime1 01.06.1900
A   1900    2   9   45tz    tztime1 01.06.1900
A   1900    3   8   45tz    tztime1 01.06.1900
A   1900    4   7   45tz    tztime1 01.06.1900
A   1900    5   6   45tz    tztime1 01.06.1900
A   1900    6   5   45tz    tztime1 01.06.1900
A   1900    7   4   45tz    tztime1 01.06.1900
A   1900    7   10  45tz    tztime1 01.06.1900
A   1900    7   9   45tz    tztime1 01.06.1900
A   1900    8   3   45tz    tztime1 01.06.1900
A   1900    8   10  45tz    tztime1 01.06.1900
A   1900    8   9   45tz    tztime1 01.06.1900
A   2000    1   10  45tz    tztime2 01.06.2000
A   2000    2   9   45tz    tztime2 01.06.2000
A   2000    3   8   45tz    tztime2 01.06.2000
A   2000    3   10  45tz    tztime2 01.06.2000
A   2000    3   9   45tz    tztime2 01.06.2000
B   1800    1   10  52fd    tztime0 01.06.1800
B   1800    2   9   52fd    tztime0 01.06.1800
B   1800    3   8   52fd    tztime0 01.06.1800
B   1800    3   10  52fd    tztime0 01.06.1800
B   1800    3   9   52fd    tztime0 01.06.1800
B   1800    4   7   52fd    tztime0 01.06.1800
B   1900    1   10  52fd    tztime1 01.06.1900
B   1900    2   9   52fd    tztime1 01.06.1900
B   1900    2   10  52fd    tztime1 01.06.1900
B   1900    2   9   52fd    tztime1 01.06.1900
",header=TRUE)
library(data.table)
setDT(test)
names(test) <-  c("ID", "Year", "Count", "value", "A","B","C")

在这个简化的数据集中,我有两个人(A 和 B),他们的年份不同但可能重叠。给出了计数以及值。

我想删除每个 YEAR 和 Count 组中每个 ID 的观察结果,它们是重复的并且满足特定条件(见下文)。例如对于组:

A   1900    7   4
A   1900    7   10
A   1900    7   9

我想删除所有观察值,其值大于每个组中的最小值。在这种情况下,我只想

A   1900    7   4

作为余数。

请注意,我的真实数据集非常大并且有更多的列。因此,如果可能的话,我正在寻找一种内存效率高的解决方案。

我希望你说得够清楚了。如果没有,请随时询问缺少的任何信息。

编辑:我的真实数据集比这里显示的列多很多,所以最后我正在寻找一个显示所有列信息的解决方案(例如,假设在这种情况下还有列 A , B 和 C 作为数据集的一部分,我在最新的编辑中添加了它们。它们并不是 grouping/filtering 真正需要的,但仍然应该是最终结果的一部分)。当前提出的解决方案没有考虑到这一点。

在 R 中,您可以用以下方式回答这个问题:test[,.(Value=min(Value)), by=.(ID, Year, Count)]

在这里,我们将浏览数据并找出每个 ID、Year 和 Count 组合的最小值。这使用包 data.table

中的 data.table 语法

根据需要删除的数据量,我认为有两种可能。

如果您要删除超过 20% 的数据,最好的选择是创建一个临时文件 table 并仅插入您想要保留的行。

否则你可以做一个查询,反正会很长。

对于 sql 部分,您似乎想保留一组的最小值,所以 ..

DELETE FROM my_table A
where exists (
 SELECT 1 FROM (
  SELECT ID, YEAR, Count, min(value) as min_value
  FROM my_table 
  GROUP BY ID, YEAR, Count) TMP
 WHERE TMP.ID = A.ID AND TMP.year = A.year AND TMP.count = A.count AND a.value > tmp.min_value)

由于逻辑上的查询,SGBD 将进行完整的 table 扫描以填充 hastable。 如果您的数据负载不是那么大(大小),您可能想尝试在所有列上创建索引:ID、YEAR、COUNT、VALUE

将SQL计划与两个案例进行比较