计算 R 中工单的持续时间

问题描述 投票:0回答:2

我有一组客户,他们的日常活动日志,以及他们的帐户是否有问题。客户在作为客户期间可以多次在其帐户上提出问题,并且问题可能会持续提出多天。我想计算出每个帐户提出问题的持续时间。日期可以从任何地方开始,问题可能随时发生,在下面的示例中保存为 TRUE=1 和 FALSE=0。

一些示例数据:

df <- data.frame(customer= c('AB','AB','AB', 'AB','AB','BC','BC','BC','CD','CD','CD','CD'), date=as.Date(c("11/09/2000","12/09/2000","13/09/2000","14/09/2000","15/09/2000","13/09/2000","14/09/2000","15/09/2000","23/05/2001","24/05/2001","25/05/2001", "26/05/2001"), "%d/%m/%Y"), 
issue=c(0,1,1,1,1,0,0,1,1,0,1,1))

我尝试制作一个索引计数器,以及此线程中发现的一些其他变体:计算 R 中上次事件以来的天数,但它不会计算连续天数(即 AB 不断显示,每个事件的持续时间为 1)天而不是2,3,4),如下图:

顾客 日期 问题 持续时间
AB 2000-09-11 0 0
AB 2000-09-12 1 1
AB 2000-09-13 1 1
AB 2000-09-14 1 1
AB 2000-09-15 1 1

我需要的输出类似于:

客户 日期 问题 持续时间
AB 2000-09-11 0 0
AB 2000-09-12 1 1
AB 2000-09-13 1 2
AB 2000-09-14 1 3
AB 2000-09-15 1 4
公元前 2000-09-13 0 0
公元前 2000-09-14 0 0
公元前 2000-09-15 1 1
CD 2000-05-23 1 1
CD 2000-05-24 0 0
CD 2000-05-25 1 1
CD 2000-05-26 1 2

任何帮助都会很棒。谢谢!

r date duration
2个回答
3
投票

(下面的所有方法都假设

first(issue)
issue[1]
本身就足够“真实”,如 n
0
FALSE
。如果您的真实数据没有那么幸运,则需要更新条件(例如,
issue[1] > 0
也可以在这里使用)。

dplyr

我们将使用

consecutive_id()
(用于行程编码),然后分组来计算天数。

library(dplyr)
df |>
  mutate(ticket = consecutive_id(customer, issue)) |>
  mutate(duration = if (first(issue)) as.numeric(date - min(date)) + 1 else 0, .by = c(customer, ticket))
#    customer       date issue ticket duration
# 1        AB 2000-09-11     0      1        0
# 2        AB 2000-09-12     1      2        1
# 3        AB 2000-09-13     1      2        2
# 4        AB 2000-09-14     1      2        3
# 5        AB 2000-09-15     1      2        4
# 6        BC 2000-09-13     0      3        0
# 7        BC 2000-09-14     0      3        0
# 8        BC 2000-09-15     1      4        1
# 9        CD 2001-05-23     1      5        1
# 10       CD 2001-05-24     0      6        0
# 11       CD 2001-05-25     1      7        1
# 12       CD 2001-05-26     1      7        2

基础R

更详细一点,逻辑相同。

df$ticket <- with(df, ave(issue, list(customer), FUN = function(z) {
  r <- rle(z)
  r$values <- seq_along(r$values) * r$values
  inverse.rle(r)
}))
df$duration <- with(df, ave(1:nrow(df), list(customer, ticket), FUN = function(i) {
  if (length(i) && issue[i][1]) {
    as.numeric(date[i] - min(date[i])) + 1
  } else rep(0, length(i))
}))
df
#    customer       date issue ticket duration
# 1        AB 2000-09-11     0      0        0
# 2        AB 2000-09-12     1      2        1
# 3        AB 2000-09-13     1      2        2
# 4        AB 2000-09-14     1      2        3
# 5        AB 2000-09-15     1      2        4
# 6        BC 2000-09-13     0      0        0
# 7        BC 2000-09-14     0      0        0
# 8        BC 2000-09-15     1      2        1
# 9        CD 2001-05-23     1      1        1
# 10       CD 2001-05-24     0      0        0
# 11       CD 2001-05-25     1      3        1
# 12       CD 2001-05-26     1      3        2

数据表

dplyr
步骤非常相似。

library(data.table)
as.data.table(df)[, ticket := rleid(issue),
                  by = "customer"
  ][, duration := if (first(issue)) as.numeric(date - min(date)) + 1 else 0,
    by = c("customer", "ticket")]

0
投票

A

data.table
oneliner 可以

library(data.table)
setDT(df)[, duration := ifelse(issue == 0, 0, date - date[1] + 1), by = .(customer, rleid(issue))]

输出

    customer       date issue duration
 1:       AB 2000-09-11     0        0
 2:       AB 2000-09-12     1        1
 3:       AB 2000-09-13     1        2
 4:       AB 2000-09-14     1        3
 5:       AB 2000-09-15     1        4
 6:       BC 2000-09-13     0        0
 7:       BC 2000-09-14     0        0
 8:       BC 2000-09-15     1        1
 9:       CD 2001-05-23     1        1
10:       CD 2001-05-24     0        0
11:       CD 2001-05-25     1        1
12:       CD 2001-05-26     1        2
© www.soinside.com 2019 - 2024. All rights reserved.