如何通过应用特定功能来聚合data.table中的重复行

时间:2019-04-19 13:03:22

标签: r data.table

我有一个data.table(r1),其中包含站点和时间的重复值。在这里,我创建了这个示例数据表,该表已经显示了为什么出现这些重复项,即我最初有两个要合并的数据表。 也许在合并dt1和dt2的阶段就可以解决我的问题了。

dt1 <- data.table(site=c(1,1,2,2), site_type="type1", time=c(1,2,1,2), temp=c(10,12,13,NA), prec=c(10,101,1,1) )
dt2 <- data.table(site=c(3,3,2,2 ), site_type="type2", time=c(1,2,1,2), temp=c(10,12,100,140), prec=c(10,101,1000,NA), snow=c(1,1,1,1))
r1 <- rbindlist(list(dt1,dt2), fill=T)

现在,我想汇总所有重复的行(4和8以及3和7),以便对于列'temp','prec','snow',这些值将取自site_type =' type1',除非它是NA。

我发现的肮脏解决方案是创建包含重复行的r1的子集,以及不包含重复行的子集。

duplicates <- r1[duplicated(r1,by=c("site","time")) | duplicated(r1,by=c("site","time"), fromLast=TRUE)]

no_duplicates <- r1[!(duplicated(r1,by=c("site","time")) | duplicated(r1,by=c("site","time"), fromLast=TRUE))]

然后将重复项聚合在一起。

aggregated_duplicates <- duplicates[, lapply(.SD, function(x) ifelse(!is.na(x[site_type=="type1"]),x[site_type=="type1"],x[site_type=="type2"])), by=c("site","time")]

然后合并Aggregated_duplicates和no_duplicates数据表。

r1_without_duplicates <- rbindlist(list(no_duplicates, aggregated_duplicates), use.names = T)

该方法似乎可行,但是我感觉可以在数据表中将dt1和dt2合并时一行完成,也可以巧妙地使用“重复”或“唯一”。

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

由于您的要求中有2个不同的操作,即(i)如果type1中有NA,则使用type2中的值;(ii)行绑定2个不同的data.table,因此我认为没有一个可以同时执行这两个代码的代码。

另一种可能的方法是在执行dt1并删除重复项之前,先更新rbindlist的NA值:

cols <- c("temp", "prec", "prec")
dt <- copy(dt1)
for (j in cols) {
    dt[is.na(get(j)), (j) := dt2[.SD, on=c("site","time"), j, with=FALSE]]
}
r2 <- rbindlist(list(dt, dt2), use.names=TRUE, fill=TRUE)
r2[!duplicated(r2, by=c("site","time"))]

输出:

   site site_type time temp prec snow
1:    1     type1    1   10   10   NA
2:    1     type1    2   12  101   NA
3:    2     type1    1   13    1   NA
4:    2     type1    2  140    1   NA
5:    3     type2    1   10   10    1
6:    3     type2    2   12  101    1