【发布时间】:2020-06-26 00:01:50
【问题描述】:
我有一个数据表dat1,其中包含多个站点的每日降雨量测量值:
> dat1
date ID value
1: 2000-03-01 1559 0
2: 2000-03-02 1559 0
3: 2000-03-03 1559 0
4: 2000-03-04 1559 0
5: 2000-03-05 1559 0
---
106178: 2019-12-27 1322 2
106179: 2019-12-28 1322 1
106180: 2019-12-29 1322 2
106181: 2019-12-30 1322 2
106182: 2019-12-31 1322 0
我还有另一个数据表dat2dat1 中的每个站点以及一些相邻站点,它们之间的距离以及它们共同的测量日期:
> dat2
ID1 ID2 dist common_date_begin common_date_end diff_days
1: 1549 1550 490774.05 2010-02-23 2017-06-16 2670
2: 1549 1551 290832.68 2010-02-23 2017-06-16 2670
3: 1549 1552 87750.38 2006-02-01 2017-06-16 4153
4: 1549 1553 138531.18 2006-02-01 2017-06-16 4153
5: 1549 1554 103870.34 2000-03-01 2017-06-16 6316
6: 1549 1555 112919.70 2000-03-01 2017-06-16 6316
7: 1549 1556 19625.65 2000-03-01 2017-06-16 6316
8: 1549 1557 398693.43 2000-03-01 2017-06-16 6316
9: 1549 1558 73514.23 2000-03-01 2017-06-16 6316
10: 1549 1559 129691.63 2000-03-01 2017-06-16 6316
对于dat2 中的每个ID1-ID2 对,我想对dat1 中的这些站点进行子集化,并计算两个站点之间的相关性。
以下代码实现了我所需要的:
library(data.table)
dat1 <- fread("https://www.dropbox.com/s/d2s61du255vzu7g/dat1.csv?dl=1") # ~2 MB
dat2 <- fread("https://www.dropbox.com/s/7n0z0gbeoifss4j/dat2.csv?dl=1") # ~5 KB
# fix column classes
dat1$date <- as.Date(dat1$date)
dat1$ID <- as.character(dat1$ID)
dat2[, (c("common_date_begin","common_date_end")) := lapply(.SD, as.Date), .SDcols = c("common_date_begin","common_date_end")]
dat2[, (c("ID1","ID2")) := lapply(.SD, as.character), .SDcols = c("ID1","ID2")]
# get list of unique stations
ids <- unique(dat2$ID1)
# initialize matrix to hold correlations
correlations <- matrix(NA, nrow = nrow(dat2), ncol=1)
# initialize data frame to hold results
results <- as.data.frame(dat2[, -c(4:5)])
# initialize loop counters
x <- 1
# loop over the main ID's
for (i in ids) {
tmp <- dat2[ID1==i]
#loop over the ID's of the neighbour stations
for (id in 1:nrow(tmp)){
# get ID of the neighbours
near_id <- as.numeric(tmp[id, 2])
# get common dates
beg_date <- tmp[id, 4]
end_date <- tmp[id, 5]
# calculate correlations
correlations[x,1] <- cor(dat1[ID==i & date %between% c(beg_date, end_date)]$value,
dat1[ID==near_id & date %between% c(beg_date, end_date)]$value)
# increment loop counter
x <- x + 1
}
}
# assemble final data frame
results <- data.table(ID=results[, 1],
ID_nearest=results[, 2],
distance=results[, 3],
overlapping_days=results[, 4],
correl=as.vector(correlations))
这个玩具示例的运行速度非常快。但是,它需要 forever 在我真实的 400 万行数据表上。我等了大约 3 个小时,还没有看到处理结束。
所以我的问题是:有什么方法可以加快上述代码的速度,不包括将其转换为 C++?由于我有 32 个内核可用,代码是否符合任何多核方法的条件? mclapply 还是 foreach?任何一个开始提示?
【问题讨论】:
标签: r parallel-processing data.table subset