我有一个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合并时一行完成,也可以巧妙地使用“重复”或“唯一”。
有什么想法吗?
谢谢!
答案 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