【问题标题】:How to determine groups which fulfill certain condition for two consecutive time periods in R如何确定在R中连续两个时间段满足特定条件的组
【发布时间】:2018-09-25 18:08:30
【问题描述】:

假设我有一个名为 data 的简单数据集:

customer_id <- c("1","1","1","2","2","2","2","3","3","3")
account_id <- as.character(c(11,11,11,55,55,55,55,38,38,38))
obs_date <- c(as.Date("2017-01-01","%Y-%m-%d"), as.Date("2017-02-01","%Y-%m-%d"), as.Date("2017-03-01","%Y-%m-%d"),
          as.Date("2017-12-01","%Y-%m-%d"), as.Date("2018-01-01","%Y-%m-%d"), as.Date("2018-02-01","%Y-%m-%d"),
          as.Date("2018-03-01","%Y-%m-%d"), as.Date("2018-04-01","%Y-%m-%d"), as.Date("2018-05-01","%Y-%m-%d"),
          as.Date("2018-06-01","%Y-%m-%d"))
variable <- c(87,90,100,120,130,150,12,13,15,14)
data <- data.table(customer_id,account_id,obs_date,variable)

我想添加另一个称为指标的变量,对于那些在两个或多个连续观察日期 (obs_date) 中具有变量

indicator <- c(1,1,1,0,0,0,0,1,1,1)
data <- data.table(customer_id,account_id,obs_date,variable, indicator)

您知道如何创建这个称为指标的变量吗?我需要按 customer_id、account_id 进行分组,并确定变量

【问题讨论】:

  • 第三条记录不会指示为 0,因为它的变量是 100,即 > 90?
  • @samadhi 每个“customer_id, account_id 对”(不是每个记录/行)和“两个或更多”行足以应用它。

标签: r data.table


【解决方案1】:

你可以...

data[, v := with(rle(variable <= 90), 
  any(lengths >= 2 & values)
), by=.(customer_id, account_id)]

    customer_id account_id   obs_date variable indicator     v
 1:           1         11 2017-01-01       87         1  TRUE
 2:           1         11 2017-02-01       90         1  TRUE
 3:           1         11 2017-03-01      100         1  TRUE
 4:           2         55 2017-12-01      120         0 FALSE
 5:           2         55 2018-01-01      130         0 FALSE
 6:           2         55 2018-02-01      150         0 FALSE
 7:           2         55 2018-03-01       12         0 FALSE
 8:           3         38 2018-04-01       13         1  TRUE
 9:           3         38 2018-05-01       15         1  TRUE
10:           3         38 2018-06-01       14         1  TRUE

要了解它是如何工作的,请看一个更简单的行:

data[, rle(variable <= 90), by=.(customer_id, account_id)]

   customer_id account_id lengths values
1:           1         11       2   TRUE
2:           1         11       1  FALSE
3:           2         55       3  FALSE
4:           2         55       1   TRUE
5:           3         38       3   TRUE

【讨论】:

  • 非常感谢,你们太棒了!我可以问一下解决方案的哪一部分可以确保如果我有例如“变量”的最后三行的值为 13,100,14 而不是 13,15,14(即不满足连续两行的条件),对于这个 customer_id、account_id 对,它的“v”是否为 FALSE?我知道在这种情况下它将是正确的 FALSE,但我只是不知道为什么。我想我不明白这个 rle() 函数是如何工作的。
  • @doremi Np :) rle 函数会将其分解为满足条件变量 lengths 每个运行 1 (使用values TRUE、FALSE、TRUE),所以lengths &gt;= 2 条件对于所有这些都将失败。试试?rle 和example(rle)
【解决方案2】:

您可以使用dplyr::lag()(或data.table::shift())查看每行中variable 的先前值,检查每行和前一行是否低于90,而不是查看每个组是否都如此。

data[, indicator := max(variable <= 90 & lag(variable) <= 90, na.rm=T), 
     by=.(customer_id, account_id)]

data 现在是:

    customer_id account_id   obs_date variable indicator
 1:           1         11 2017-01-01       87         1
 2:           1         11 2017-02-01       90         1
 3:           1         11 2017-03-01      100         1
 4:           2         55 2017-12-01      120         0
 5:           2         55 2018-01-01      130         0
 6:           2         55 2018-02-01      150         0
 7:           2         55 2018-03-01       12         0
 8:           3         38 2018-04-01       13         1
 9:           3         38 2018-05-01       15         1
10:           3         38 2018-06-01       14         1

为了说明发生了什么:

data[, .(obs_date, 
         variable, 
         lag = lag(variable),
         both_below = variable <= 90 & lag(variable) <= 90
       ), by=.(customer_id, account_id)]

输出:

    customer_id account_id   obs_date variable lag both_below
 1:           1         11 2017-01-01       87  NA         NA
 2:           1         11 2017-02-01       90  87       TRUE
 3:           1         11 2017-03-01      100  90      FALSE
 4:           2         55 2017-12-01      120  NA      FALSE
 5:           2         55 2018-01-01      130 120      FALSE
 6:           2         55 2018-02-01      150 130      FALSE
 7:           2         55 2018-03-01       12 150      FALSE
 8:           3         38 2018-04-01       13  NA         NA
 9:           3         38 2018-05-01       15  13       TRUE
10:           3         38 2018-06-01       14  15       TRUE    

【讨论】:

  • 感谢您使用lag,我试图在ifelse 之后以这种方式回答它,但没有它会更容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多