首页 > 解决方案 > 使用聚合操作时如何避免在 data.table 中创建重复项

问题描述

我正在使用一个data.table对象来加快一些聚合操作。我的数据集的实际大小超过 1 亿行,因此我为这个问题包含了虚拟数据。我的data.table对象是Sample3(我在最后一面添加版本) ,dput()它由 5 个变量组成:DateIdValue和. 我想通过并执行聚合任务来计算:行数,:值的总和,:值的平均值和:与最大值之间的差异。我为该任务使用了下一个代码:WeekDayIdWeekNumberSumAvgDiffDayDate

library(data.table)
#Compute
Summary <- Sample3[,.(Number=.N,Sum=sum(Value),Avg=mean(Value),
                                          Diff=Day-max(Date)),by = .(Id,Week)]  

计算是正确的,但是有一个问题,Summary有重复的行,当所需的输出应该只有 1 个观察值时,根据IdWeek。此外,Sample3有 11 行并且Summary具有相同的行数。我没有使用:=运算符。这是我得到的输出:

       Id    Week Number       Sum      Avg   Diff
 1: 923996 48-2014      5 21.690579 4.338116 5 days
 2: 923996 48-2014      5 21.690579 4.338116 5 days
 3: 923996 48-2014      5 21.690579 4.338116 5 days
 4: 923996 48-2014      5 21.690579 4.338116 5 days
 5: 923996 48-2014      5 21.690579 4.338116 5 days
 6: 923996 49-2014      3 22.115795 7.371932 2 days
 7: 923996 49-2014      3 22.115795 7.371932 2 days
 8: 923996 49-2014      3 22.115795 7.371932 2 days
 9: 923996 50-2014      1  5.101146 5.101146 3 days
10: 923996 51-2014      2  6.086128 3.043064 1 days
11: 923996 51-2014      2  6.086128 3.043064 1 days

的正确输出Summary应如下所示:

     Id    Week Number       Sum      Avg   Diff
1: 923996 48-2014      5 21.690579 4.338116 5 days
2: 923996 49-2014      3 22.115795 7.371932 2 days
3: 923996 50-2014      1  5.101146 5.101146 3 days
4: 923996 51-2014      2  6.086128 3.043064 1 days

我不知道为什么这个单一操作会发生这种行为,并且在大数据集中有重复的行可能会导致更多的时间来完成删除它们的任务。就像每一行都在更新。的dput()版本Sample3是下一个:

Sample3 <- structure(list(Date = structure(c(16405, 16405, 16406, 16406, 
16406, 16407, 16409, 16409, 16415, 16421, 16424), class = "Date"), 
    Id = c(923996L, 923996L, 923996L, 923996L, 923996L, 923996L, 
    923996L, 923996L, 923996L, 923996L, 923996L), Value = c(5.69822266467209, 
    3.11110428877822, 4.74334486914574, 2.17729208527479, 5.96061541361928, 
    7.60801375507644, 4.3689394081637, 10.1388420642027, 5.10114642099159, 
    0.022944125999933, 6.06318436387287), Week = c("48-2014", 
    "48-2014", "48-2014", "48-2014", "48-2014", "49-2014", "49-2014", 
    "49-2014", "50-2014", "51-2014", "51-2014"), Day = structure(c(16411, 
    16411, 16411, 16411, 16411, 16411, 16411, 16411, 16418, 16425, 
    16425), class = "Date")), row.names = c(NA, -11L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x0000000000311ef0>)

我是新手,data.table也许这是一个非常简单的解决方案,但我搜索了其他帖子,但没有找到修改这种情况的方法。谢谢你的帮助。

标签: rdata.table

解决方案


您获得多行的原因是因为此代码产生一个向量而不是单个值:

Diff=Day-max(Date)

您只需要[1](或min

library(data.table)
Sample3[,.(Number=.N,Sum=sum(Value),Avg=mean(Value),
            Diff=Day[1]-max(Date)),by = .(Id,Week)] 
#       Id    Week Number       Sum      Avg   Diff
#1: 923996 48-2014      5 21.690579 4.338116 5 days
#2: 923996 49-2014      3 22.115795 7.371932 2 days
#3: 923996 50-2014      1  5.101146 5.101146 3 days
#4: 923996 51-2014      2  6.086128 3.043064 1 days

正如@Uwe 所指出的,其中的一些函数data.table可能有助于优化代码的速度,例如firstlast如果您的数据已经按日期排列。


推荐阅读