Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R-使用数据表循环子集和获取输出的最快方法(计算每月度量值)_R_Performance_Loops_Dataframe_Subset - Fatal编程技术网

R-使用数据表循环子集和获取输出的最快方法(计算每月度量值)

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-

我有一个问题,我希望计算一些不同实体的每月措施,但我目前使用的代码似乎非常缓慢。我想知道你是否知道一个更好的解决办法

下面是我的数据集的简化版本。问题是其中一个数据集包含了大约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-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)
}