【问题标题】:Efficient way in R to count lines per ID on sliding time window?R中计算滑动时间窗口上每个ID的行数的有效方法?
【发布时间】:2016-09-05 21:12:47
【问题描述】:

是否有任何包中的任何函数可以计算行中的 ID 在过去 x 小时出现了多少次。我将其称为“速度”。

我确实要计算的目标列由“VEL_7H”表示。换言之,该 ID 在过去 7 小时内出现了多少次?

ID        TIME                   VEL_7H
1144727   2016-04-01 09:56:12    0
1144727   2016-04-01 15:16:03    1
1144727   2016-04-01 15:26:14    2
1144727   2016-04-02 09:48:48    0
1799567   2016-04-14 14:41:06    0
1799567   2016-04-14 17:51:06    1
2067650   2016-04-17 12:34:52    0

是否有使用时间和 ID 向量以及指定范围的函数来提供 VEL_7H 列?

【问题讨论】:

  • 您能提供一个dput(your_example) 以便更容易复制粘贴到 R 中吗?

标签: r dataset sliding-window


【解决方案1】:

为了最大化性能,我认为Rcpp 是合适的:

library(Rcpp);
df <- data.frame(ID=c(1144727L,1144727L,1144727L,1144727L,1799567L,1799567L,2067650L),TIME=as.POSIXct(c('2016-04-01 09:56:12','2016-04-01 15:16:03','2016-04-01 15:26:14','2016-04-02 09:48:48','2016-04-14 14:41:06','2016-04-14 17:51:06','2016-04-17 12:34:52')));
cppFunction('
    IntegerVector countTrailingIDs(IntegerVector ids, DoubleVector times, double window ) {
        IntegerVector res(ids.size());
        for (int i = 0; i < ids.size(); ++i) {
            int id = ids[i];
            double trailTime = times[i]-window;
            for (int j = i-1; j >= 0 && ids[j] == id && times[j] >= trailTime; --j)
                ++res[i];
        }
        return res;
    }
');
df$VEL_7H <- countTrailingIDs(df$ID,df$TIME,60*60*7);
df;
##        ID                TIME VEL_7H
## 1 1144727 2016-04-01 09:56:12      0
## 2 1144727 2016-04-01 15:16:03      1
## 3 1144727 2016-04-01 15:26:14      2
## 4 1144727 2016-04-02 09:48:48      0
## 5 1799567 2016-04-14 14:41:06      0
## 6 1799567 2016-04-14 17:51:06      1
## 7 2067650 2016-04-17 12:34:52      0

注意该功能需要idstimes先按id排序,再按时间排序。

【讨论】:

  • 哇。非常快速和简单(立即计算 1.6M 速度)。感谢您的解决方案,我会接受答案。
【解决方案2】:

我们可以在基础 R 中使用经典的 split-apply-combine 方法,首先按 ID 拆分数据框,将过去 7 小时内的条目数量相加,然后使用值创建一个新列:

sdf <- split(df, df$ID)
last7 <- function(df) sapply(1:nrow(df), function(i) sum(df[i, "TIME"] - df[1:i, "TIME"] <= 60*60*7) - 1L)
df$VEL_7H <- unlist(sapply(sdf, last7))
df
#        ID                TIME VEL_7H
# 1 1144727 2016-04-01 09:56:12      0
# 2 1144727 2016-04-01 15:16:03      1
# 3 1144727 2016-04-01 15:26:14      2
# 4 1144727 2016-04-02 09:48:48      0
# 5 1799567 2016-04-14 14:41:06      0
# 6 1799567 2016-04-14 17:51:06      1
# 7 2067650 2016-04-17 12:34:52      0

【讨论】:

  • 谢谢。很高兴看到这些基本 R 函数提供了简单的解决方案。我仍然认为某些包中没有执行此类操作的功能很奇怪。赞成(:
猜你喜欢
  • 1970-01-01
  • 2011-01-10
  • 2019-02-09
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 2016-08-01
相关资源
最近更新 更多