我有很多大型(300k-1M行)数据框,我试图通过遍历数据框(df_i
)来附加值,对于每个数据框,遍历行并询问其中的值第二个数据帧是(do2
),位于匹配的纬度,经度,月份和深度。纬度/经度/月将完全匹配,深度更复杂,因为do2在增加的深度箱中具有57列值:
我的行循环代码的核心是3行行子集和列子集:
for (j in 1:nrow(df_i)) {
df_i[j,"DO2"] <- do2[do2$Latitude == df_i[j,"latbin"] &
do2$Longitude == df_i[j,"lonbin"] &
do2$Month == month(df_i[j,"DateTimeUTCmin5"]),
which.min(abs(depthbins - df_i[j, "Depth.m."])) + 3]
}
这有效,但是很慢。我知道它可能会加快速度,但是我的并行化工作一直很艰难,并且并行进行调试/回溯要困难得多。我在阅读this之后尝试了FBM,但得到
值必须是唯一的或具有x [i,j]的尺寸
大约有20万行。我了解data.table indexes are fast,所以可能像Frank's comment here一样可行,也许是data.table中的多行子集?但这大概与我现有的解决方案相同(因为我也需要对子集/查找列进行处理),也许更快一点?
有人知道更聪明的方法吗?以前,我对Apply函数感到困惑,但是如果那里有用的话,不会感到惊讶吗?
谢谢。
可重现(简化的月份,像以前一样省略了depthbin的添加):
depthbins <- c(0,5,10,15,20,25,50,75,100,125,150,200,250,300,350,400)
df_i <- data.frame(latbin = c(-77.5, -78, -78.5),
lonbin = c(-178.5, -177.5, -176.5),
month = c(1,2,3),
Depth.m. = c(130,120,110))
do2 <- tibble(Month = c(1,1,1),
Latitude = c(-78,-78,-79),
Longitude = c(-178.5, -177.5, -177.5),
"0" = c(214, 223, 345),
"5" = c(123,234,345),
"10" = c(345,456,567))
最终编辑:对Marius代码的一些调整:
do2 %<>% gather(.vars = colnames(do2)[4:length(colnames(do2))],
key = "depbin", value = "DO2")
do2$depbin <- as.numeric(do2$depbin)
depthbins <- sort(unique(do2$depbin))
df_i$depbin = sapply(df_i$Depth.m., function(d) depthbins[which.min(abs(depthbins - d))])
df_i %<>% left_join(do2, by = c("Month" = "Month",
"latbin" = "Latitude",
"lonbin" = "Longitude",
"depbin" = "depbin")) %>%
select(-Month, -latbin, -lonbin, -depbin)
答案 0 :(得分:1)
我认为只要稍加重组就可以将其合并。合并部分应该比for循环方法快得多,这将因git tags
的大小增加和准备时间而稍有偏移。注意,我不得不对示例数据进行一些修改,以便每一行实际上都可以与之匹配:
git-semver-tags