R-使用数据表循环子集和获取输出的最快方法(计算每月度量值)
我有一个问题,我希望计算一些不同实体的每月措施,但我目前使用的代码似乎非常缓慢。我想知道你是否知道一个更好的解决办法 下面是我的数据集的简化版本。问题是其中一个数据集包含了大约600万个每日观察值,而我目前的方法似乎非常缓慢R-使用数据表循环子集和获取输出的最快方法(计算每月度量值),r,performance,loops,dataframe,subset,R,Performance,Loops,Dataframe,Subset,我有一个问题,我希望计算一些不同实体的每月措施,但我目前使用的代码似乎非常缓慢。我想知道你是否知道一个更好的解决办法 下面是我的数据集的简化版本。问题是其中一个数据集包含了大约600万个每日观察值,而我目前的方法似乎非常缓慢 date event id return 2000-07-06 2 1 0.1 2000-07-07 1 1 0.2 2000-07-09 0 1 0.6 2000-07-10 0 1 0.4 2000-
date event id return
2000-07-06 2 1 0.1
2000-07-07 1 1 0.2
2000-07-09 0 1 0.6
2000-07-10 0 1 0.4
2000-07-15 2 1 0.7
2000-07-16 1 1 0.3
2000-07-20 0 1 0.1
2000-07-21 1 1 0.2
2000-07-06 1 2 0.3
2000-07-07 2 2 0.4
2000-07-15 0 2 0.6
2000-07-16 0 2 0.8
2000-07-17 2 2 0.9
2000-07-18 1 2 0.1
为了计算这些度量,我运行的代码如下所示:
for (j in 1:length(list.of.ids)) {
for (i in 1:(number.of.months) {
temp <- subset(data, data$date < FirstDayMonth[i+1] & data$date >= FirstDayMonth[i] & data$id == list.of.ids[j])
total[i,j+1] <- sum(temp$return, na.rm = TRUE)
}
}
用于(j/1:长度(ID列表)){
对于(i in 1:(月数){
temp=FirstDayMonth[i]&数据$id==list.of.id[j])
总[i,j+1]应产生加速的改进:
for (j in 1:length(list.of.ids)) {
id1 <- data$id == list.of.ids[j]
# outside 2nd loop so no redundant operations wont be made
for (i in 1:(number.of.months)) {
id2 <- data$date < FirstDayMonth[i+1] & data$date >= FirstDayMonth[i]
total[i, j+1] <- sum(data$return[id1 & id2], na.rm = TRUE)
}
}
如果需要,最终结果可以转换为矩阵:
m <- matrix(res$V1, nrow = length(unique(res$ym)))
m
# [,1] [,2]
# [1,] 2.6 3.1
使用aggregate
。年-月变量ym
我们可以使用日期列第一到第七个字符的substr
ing创建
m <- with(dat, aggregate(list(return=return),
by=list(ym=substr(date, 1, 7), id=id), sum))
m
# ym id return
# 1 2000-07 1 2.6
# 2 2000-07 2 3.1
资料
dat这应该快得多:
for(i in 1:length(number.of.months)) {
inds <- dat$date < FirstDayMonth[i+1] & dat$date >= FirstDayMonth[i]
total[i,] <- rowsum(dat$result[inds], dat$id[inds], na.rm=TRUE)
}
for(1中的i:长度(月数)){
inds=第一天月[i]
总计[i,]您好!这看起来真的很好。我正计划尝试使用datatables来完成这项工作。但我不确定如何存储输出/将它们保存为单独的输出。希望了解更多有关这方面的信息。谢谢!@Rnovice查看我的编辑。我对第一种方法是否能提高您所需的速度感兴趣,因为它更容易融入您的工作中r现有代码。我现在就开始吧!我已经运行了5个ID的代码。结果如下。我使用了system.time命令。用户系统运行了49.855 19.579 69.979
,问题是我有855个ID,所以我仍然不确定这在我想做的事情下是否可行。我还计算了多个月的度量值我需要极大地加快此过程,以便能够在合理的时间范围内完成。data table方法似乎是最快的/Hi!当我尝试运行您的代码时,它会返回以下错误:中的错误[也许您可以提供一个实际数据集的示例?要知道您这边的一切情况有点困难。例如,您在代码中使用了FirstDayOfMonth
,但问题中没有提供这些内容。您好!您使用的是minem创建的ym变量吗?我猜您是,但我只是想知道check@Rnovice其实不是,,它是用substr(dat$date,1,7)
创建的,即日期的第一个到第七个字符。太好了!我如何将它很好地放入矩阵中存储?对不起,我只是想了解整个过程。@Rnovice存储矩阵是什么意思,你能举个例子吗?
resdt <- dcast(res, ym ~ id, value.var = 'V1') # change data structure
resdt[1:2, 1:3]
# ym 1 2
# 1: 2000-01 6.824182 2.535805
# 2: 2000-02 3.825659 6.769578
resdt[, ym := NULL] # delets ym
setcolorder(resdt, neworder = list.of.ids) # reorder columns
m <- as.matrix(resdt)
m[1:2, 1:2]
# 1 2 3
# [1,] 6.824182 2.535805 -1.193692
# [2,] 3.825659 6.769578 -1.117223
m <- with(dat, aggregate(list(return=return),
by=list(ym=substr(date, 1, 7), id=id), sum))
m
# ym id return
# 1 2000-07 1 2.6
# 2 2000-07 2 3.1
m <- with(dat, tapply(return, list(ym=substr(date, 1, 7), id=id), sum))
m
# id
# ym 1 2
# 2000-07 2.6 3.1
dat <- structure(list(date = c("2000-07-06", "2000-07-07", "2000-07-09",
"2000-07-10", "2000-07-15", "2000-07-16", "2000-07-20", "2000-07-21",
"2000-07-06", "2000-07-07", "2000-07-15", "2000-07-16", "2000-07-17",
"2000-07-18"), event = c(2L, 1L, 0L, 0L, 2L, 1L, 0L, 1L, 1L,
2L, 0L, 0L, 2L, 1L), id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 2L), return = c(0.1, 0.2, 0.6, 0.4, 0.7, 0.3,
0.1, 0.2, 0.3, 0.4, 0.6, 0.8, 0.9, 0.1)), row.names = c(NA, -14L
), class = "data.frame")
for(i in 1:length(number.of.months)) {
inds <- dat$date < FirstDayMonth[i+1] & dat$date >= FirstDayMonth[i]
total[i,] <- rowsum(dat$result[inds], dat$id[inds], na.rm=TRUE)
}