【问题标题】:Calculate time elapsed within runs of a variable计算变量运行中经过的时间
【发布时间】:2016-02-17 00:36:44
【问题描述】:

我有一个包含时间和输出列的数据文件。 输出列由值 1 和 2 组成。 对于值为 2 的输出列的每次运行,我想计算运行期间经过的总时间,即结束时间减去开始时间。例如:

    time          output       total
      2                2           4-2=2
      4                2
      6                1
      8                2           10-8=2
      10               2
      12               1
      14               1
      16               1
      18               2           22-18=4
      20               2
      22               2

对于大型数据帧有什么简单的方法吗?

【问题讨论】:

  • 我不太确定你在问什么,但听起来你需要lagdiff

标签: r


【解决方案1】:

听起来您希望每次运行输出变量所经过的时间,其中该变量等于 2。

一种方法是use dplyr to group by runs,过滤到输出类型 2 的运行,然后计算经过的时间:

library(dplyr)
dat %>%
  group_by(run={x = rle(output) ; rep(seq_along(x$lengths), x$lengths)}) %>%
  filter(output == 2) %>%
  summarize(total=max(time)-min(time))
# Source: local data frame [3 x 2]
# 
#     run total
#   (int) (dbl)
# 1     1     2
# 2     3     2
# 3     5     4

这也可以在基础 R 中使用 rle 函数完成:

x <- rle(dat$output)
unname(tapply(dat$time, rep(seq_along(x$lengths), x$lengths), function(x) max(x)-min(x))[x$values == 2])
# [1] 2 2 4

【讨论】:

    【解决方案2】:

    这是另一种方式。我用rleid() 创建了一个名为foo 的组变量。对于每个组,我从最后一个output 值中减去第一个output 值,即total。然后,我用 NA 替换了 total 中的所有值,其中 output 不是 2。然后,对于每个组,我分配了一个向量,包括 total 的第一个值和 NA。最后,我删除了 group 变量。

    library(data.table)
    
    mydf <- data.frame(time = c(2,4,6,8,10,12,14,16,18,20,22),
                       output = c(2,2,1,2,2,1,1,1,2,2,2))
    
    setDT(mydf)[, foo := rleid(output)][,
        total := last(time) - first(time), by = "foo"][,
        total := replace(total, which(output !=2), NA)][,
        total := c(total[1L], rep(NA, .N - 1)), by = "foo"][, -3, with = FALSE][]
    
    #    time output total
    # 1:    2      2     2
    # 2:    4      2    NA
    # 3:    6      1    NA
    # 4:    8      2     2
    # 5:   10      2    NA
    # 6:   12      1    NA
    # 7:   14      1    NA
    # 8:   16      1    NA
    # 9:   18      2     4
    #10:   20      2    NA
    #11:   22      2    NA
    

    【讨论】:

      【解决方案3】:

      我了解到您想按 Outlook 的“运行”分组?

      首先我们需要索引“运行”。我创建了一个基于 rle 的函数(我找不到任何可以执行此操作的函数,但它可能已经存在)。

      indexer <-function(x){
        run <- rle(x)$length
        size <- length(run)
        value <- c()
        for(i in 1:size){
          value = c(value, rep(i,run[i]))
          }
        value
        }
      
      df$index <- indexer(df$output)
      
      df %>% group_by(index) %>% mutate(total = max(time) - min(time))
      
          time output index total
      1      2      2     1     2
      2      4      2     1     2
      3      6      1     2     0
      4      8      2     3     2
      5     10      2     3     2
      6     12      1     4     4
      7     14      1     4     4
      8     16      1     4     4
      9     18      2     5     4
      10    20      2     5     4
      11    22      2     5     4
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 2020-12-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        • 2010-11-15
        相关资源
        最近更新 更多