r语言 - 基于条件的折叠



这个问题类似于几天前已经发布的问题, 折叠行从 0 到 0

这里与上一个问题不同的新转折是,我们如何仅对时间差异小于或等于 60 的行按 Id 折叠行。

例如,使用相同的数据集

Incident.ID..                date           product
INCFI0000029582     2014-09-25 08:39:45     foo
INCFI0000029582     2014-09-25 08:39:45     foo
INCFI0000029582     2014-09-25 08:39:48     bar 
INCFI0000029582     2014-09-25 08:40:44     foo
INCFI0000029582     2014-10-10 23:04:00     foo
INCFI0000029587     2014-09-25 08:33:32     bar
INCFI0000029587     2014-09-25 08:34:41     bar
INCFI0000029587     2014-09-25 08:35:24     bar
INCFI0000029587     2014-10-10 23:04:00     foo

df <- structure(list(Incident.ID.. = c("INCFI0000029582", "INCFI0000029582","INCFI0000029582", 
"INCFI0000029582", "INCFI0000029582", "INCFI0000029587", "INCFI0000029587", 
"INCFI0000029587", "INCFI0000029587"), date = c("2014-09-25 08:39:45","2014-09-25 08:39:45", 
"2014-09-25 08:39:48", "2014-09-25 08:40:44", "2014-10-10 23:04:00", 
"2014-09-25 08:33:32", "2014-09-25 08:34:41", "2014-09-25 08:35:24", 
"2014-10-10 23:04:00"), product = 
c("foo","foo","bar","foo","foo","bar","bar","bar","foo")), 
class = "data.frame", row.names = c(NA, 
-L))

这将按 ID 计算时差

 library(dplyr)
 library(lubridate)
 df1 <- df %>%
  group_by(Incident.ID..) %>%
  arrange(ymd_hms(date)) %>%
  mutate(diff = c(0, diff(ymd_hms(date))))

这会导致这个新的列差异,如下所示

Incident.ID..   date                 product    diff
INCFI0000029582 2014-09-25 08:39:45  foo        0
INCFI0000029582 2014-09-25 08:39:45  foo        0
INCFI0000029582 2014-09-25 08:39:48  bar        3
INCFI0000029582 2014-09-25 08:40:44  foo        56
INCFI0000029582 2014-10-10 23:04:00  foo        1347796
INCFI0000029587 2014-09-25 08:33:32  bar        0
INCFI0000029587 2014-09-25 08:34:41  bar        69
INCFI0000029587 2014-09-25 08:35:24  bar        43
INCFI0000029587 2014-10-10 23:04:00  foo        1348116

现在只将时差小于或等于 60 的行折叠Incident.ID..,即diff <= 60应该得到这样的最终数据集

 Incident.ID..     DateMin              DateMax              product      diff_collapse
 INCFI0000029582   2014-09-25 08:39:45  2014-09-25 08:40:44  foo,bar,foo  0,0,3,56
 INCFI0000029582   2014-09-25 08:40:44  2014-10-10 23:04:00  foo          1347796
 INCFI0000029587   2014-09-25 08:33:32  2014-09-25 08:34:41  bar          0
 INCFI0000029587   2014-09-25 08:34:41  2014-09-25 08:35:24  bar,bar      69,43
 INCFI0000029587   2014-09-25 08:35:24  2014-10-10 23:04:00  foo          1348116

寻求有关如何创建此类折叠数据集的一些帮助。提前谢谢。

我建议创建一个新的分组变量。我得到了理想的结果,如下所示:

df1 <- df %>%
  group_by(Incident.ID..) %>%
  arrange(ymd_hms(date)) %>%
  mutate(diff = c(0, diff(ymd_hms(date)))) %>%
  ungroup() %>%
  arrange(Incident.ID.., date) %>%
  mutate(group = cumsum(diff > 60 | diff == 0)) %>%
  group_by(group) %>%
  summarise(DateMin = min(date), 
            DateMax = max(date), 
            diff_collapse = toString(diff),
            product = toString(product))

我基本上是通过条件diff > 60 | diff == 0决定新组应该从哪一行开始:diff > 60因为这是崩溃条件,diff == 0是因为那是新事件开始的时候。你也可以写Incident.ID.. != lag(Incident.ID..).将其包装在cumsum中会在每次启动新组时增加计数器。

首先ungroup很重要,否则cumsum只能在组中工作。

您需要一个满足您需求的分组列:

... %>% mutate(
  grp = ifelse(diff <= 60,
               paste0(Incident.ID.., "origin"), 
               paste0(Incident.ID.., diff)
  ))
这将创建一个石斑鱼,对于

差异小于 60 的行,该石斑鱼相同(在 Incident.ID.. 以内(,否则是唯一的。(假设diff是唯一的---如果重复的差异可能大于 60,请在paste中使用 row_number() 而不是 diff 以确保它是唯一的。将其用作折叠代码的分组列。

相关内容

  • 没有找到相关文章

最新更新