首页 > 解决方案 > 如何根据日期汇总数据框?

问题描述

我在 Windows 10 上使用 R 3.5.0。

我有一个使用 library(openxls) read.xls("...."). 它有 100 000 行,其中一部分看起来像

S.No Start.DateEnd.Date  Generation    unitout     timediff
7850   42907.76 42907.77 436.158469    INSERVICE       15
7851   42907.77 42907.78 443.302793    INSERVICE       15
7852   42907.78 42907.79 437.728683    INSERVICE       15
7853   42907.79 42907.80 390.832887    INSERVICE       15
7854   42907.80 42907.81 338.917658    INSERVICE       15
7855   42907.81 42907.82 300.056018    INSERVICE       15
7856   42907.82 42907.83 266.430064    INSERVICE       15
7857   42907.83 42907.84 248.952525    INSERVICE       15
7858   42907.84 42907.85 212.913333    INSERVICE       15
7859   42907.85 42907.86  18.523060    INSERVICE       15
7860   42907.86 42907.88   1.355428 OUTOFSERVICE       15
7861   42907.88 42907.89   1.355428 OUTOFSERVICE       15
7862   42907.89 42907.90   1.355428 OUTOFSERVICE       15
7863   42907.90 42907.91   1.355428 OUTOFSERVICE       15
7864   42907.91 42907.92   1.355428 OUTOFSERVICE       15
7865   42907.92 42907.93   1.355428 OUTOFSERVICE       15
7866   42907.93 42907.94   1.355428 OUTOFSERVICE       15
7867   42907.94 42907.95   1.355428 OUTOFSERVICE       15
7868   42907.95 42907.96   1.355428 OUTOFSERVICE       15
7869   42907.96 42907.97   1.355428 OUTOFSERVICE       15
7870   42907.97 42907.98   1.355428 OUTOFSERVICE       15

我想总结一下,给我一个表格的数据框

1 DateTime1(42907.76) DateTime2(42907.86) INSERVICE      TIMEDIFF
2 DateTime2(42907.86) DateTime3(42907.98) OUTOFSERVICE   TIMEDIFF
3 DateTime3(42907.98) DateTime4(...)      INSERVICE      TIMEDIFF

每次状态从 INSERVICE 更改为 OUTOFSERVICE 时,它都会捕获开始日期和结束日期。基本上我想知道从哪个日期+时间到哪个日期+时间它在服务中和不在服务中总结在一个数据框中。在上面的示例中,DateTime1 将是 42907.76,DateTime2 将是 42907.86,因为之后它就停止服务了。同样 DateTime2 将是 42907.86 到 42907.98.So on..

我尝试创建一个标志来解决它,但我无法创建数据框,所以我没有在此处附加代码。我的偏好是使用具有良好逻辑的易于理解的解决方案,而不是使用在后端完成所有操作的包。

PS 另一个问题是将 Excel 时间格式转换为标准 %Y%m%D%H%M 格式。我已经阅读了 SO 上的多个线程,并且我尝试过 as.posixCT、as.date 等,但它要么更改为 NA,要么引发错误。

标签: rdate

解决方案


使用dplyr

我们创建了 unitout 的滞后,并使用它来创建一个 ID,之后我们可以在其上进行分组

library(dplyr)
df$id <- cumsum(as.integer(df$unitout != lag(df$unitout, n = 1, default=1))) 
df %>% group_by(id, unitout) %>% summarise("Start" = min(Start.Date), "End" = max(End.Date))

您可以通过以下方式转换日期:

  • 视窗Excel:as.Date(42907.76, origin = "1899-12-30")
  • Mac Excel:as.Date(42907.76, origin = "1904-01-01")

数据

df <- read_table(
"S.No Start.Date  End.Date  Generation  unitout       timediff
7850   42907.76   42907.77  436.158469  INSERVICE     15
7851   42907.77   42907.78  443.302793  INSERVICE     15
7852   42907.78   42907.79  437.728683  INSERVICE     15
7853   42907.79   42907.80  390.832887  INSERVICE     15
7854   42907.80   42907.81  338.917658  INSERVICE     15
7855   42907.81   42907.82  300.056018  INSERVICE     15
7856   42907.82   42907.83  266.430064  INSERVICE     15
7857   42907.83   42907.84  248.952525  INSERVICE     15
7858   42907.84   42907.85  212.913333  INSERVICE     15
7859   42907.85   42907.86  18.523060   INSERVICE     15
7860   42907.86   42907.88  1.355428    OUTOFSERVICE  15
7861   42907.88   42907.89  1.355428    OUTOFSERVICE  15
7862   42907.89   42907.90  1.355428    OUTOFSERVICE  15
7863   42907.90   42907.91  1.355428    OUTOFSERVICE  15
7864   42907.91   42907.92  1.355428    OUTOFSERVICE  15
7865   42907.92   42907.93  1.355428    OUTOFSERVICE  15
7866   42907.93   42907.94  1.355428    OUTOFSERVICE  15
7867   42907.94   42907.95  1.355428    OUTOFSERVICE  15
7868   42907.95   42907.96  1.355428    OUTOFSERVICE  15
7869   42907.96   42907.97  1.355428    OUTOFSERVICE  15
7870   42907.97   42907.98  1.355428    OUTOFSERVICE  15")

推荐阅读