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

时间:2016-09-08 13:36:37

标签: r filter duplicates data.table sqldf

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

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),不同但可能重叠的年份。给出一个Count,以及一个值。

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

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

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

A   1900    7   4

作为剩余部分。

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

我希望这很清楚。如果没有,请随时询问缺少的任何信息。

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

2 个答案:

答案 0 :(得分:2)

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

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

中的data.table语法

答案 1 :(得分:1)

根据需要删除的数据量,我的观点有两种可能性。

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

否则你可以进行查询,无论如何都要长。

对于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将执行全表扫描以填充hastable。 如果您的数据负载不是那么大(大小),您可能想尝试在所有列上创建索引:ID,YEAR,COUNT,VALUE

将SQL计划与两种情况进行比较