基于一列中的最小值,对数据表进行聚合以去重。

3

我对R中的data.table包非常陌生,使用的版本是1.8.2。

我的数据表约有2100万行,因此理想情况下我希望使用data.table方法来解决我的问题,因为这是处理大数据的主要方法。以下是样本数据和代码:

samp_data <- data.frame(user1 = c(24, 24, 24, 56, 75, 75),
                        user2 = c(43, 43, 57, 34, 61, 61),  
                        amount1 = c(1, 4, 3, 2, 6, 8), 
                        amount2 = c(4, 7, 9, 3, 5, 6), 
                        PURCH_DATE_1 = as.Date(c("2012-01-01", "2012-04-29", 
                        "2012-03-02", "2012-06-15", "2012-03-17", "2012-09-25")), 
                        PURCH_DATE_2 = as.Date(c("2012-04-01", "2012-01-25", 
                        "2012-05-21","2012-08-18", "2012-04-03", "2012-10-29")))
samp_data$DIFF_DAYS <- abs(as.numeric(samp_data$PURCH_DATE_1-
samp_data$PURCH_DATE_2))
samp_data_new<-data.table(samp_data)

我想要返回一个数据表,其中包含7个原始列,但是当user1和user2列中有重复对时,将保留DIFF_DAYS列中具有最小值的行。
假设我已经让你们混淆了我的意思,下面的代码包含所需的输出:
samp_data_desired<-data.frame(user1=c(24,24,56,75),user2=c(43,57,34,61),
                              amount1=c(1,3,2,6),amount2=c(4,9,3,5),
                              PURCH_DATE_1=as.Date(c("2012-01-01","2012-03-02",
                              "2012-06-15","2012-03-17")),
                              PURCH_DATE_2=as.Date(c("2012-04-01","2012-05-21",
                              "2012-08-18","2012-04-03")),
                              DIFF_DAYS=c(91,80,64,17))

我知道如何使用DT[, min(col1), by=user1]这样的方法执行简单的聚合,以查找每个user1的平均值、最小值和最大值,但我无法成功使用unique或duplicated函数。我尝试过:

samp_data_check <- data.table(samp_data, key=c("user1", "user2", 
                            "amount1", "amount2", "PURCH_DATE_1",
                            "PURCH_DATE_2"))

并且
samp_data_test <- samp_data_check[, unique(DIFF_DAYS), by=c("user1", 
                  "user2", "amount1", "amount2", "PURCH_DATE_1", 
                  "PURCH_DATE_2")]

我看到了一些变化,但是我已经非常困惑了,所以任何帮助都将不胜感激。


2
我建议您更新 data.table 的版本。最新的稳定版本是1.8.8。 - Arun
1个回答

6

我能想到的第一种方法(与data.table没有太多关系,只需将关键列设置为DIFF_DAYS)。 假设您的data.table是DT:

setkey(DT, "DIFF_DAYS")
DT[!duplicated(DT[, c("user1", "user2")])]

另一种方法(更适用于data.table):

setkey(DT, "user1", "user2", "DIFF_DAYS")
key.DT <- unique(DT[, 1:2])
DT[key.DT, mult = "first"]

感谢你的回答,Arun。这似乎是一个很简单的问题,但我就是想不出来,让我非常烦恼。你的解决方案很棒,我非常感激你的帮助。 - Lorcan Treanor
我很想知道这两种方法之间是否存在运行时差异(不计算在两种情况下设置密钥所花费的时间)。如果您能回复(关于2100万行),那就太好了! - Arun
1
嗨,阿伦,回复晚了很抱歉,工作比较忙。原始数据集包含 21,048,612 行,其中包含 7 个数字列和 2 个日期列。第二种方法花费了 3.180583 分钟。第一种方法需要 2.419069 分钟。希望这可以帮到你,并再次感谢提供的解决方案。如果您需要了解其他信息,请告诉我。 - Lorcan Treanor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接