我正在构建基于this helpful post的东西 . 我有三个与数据集 df
相关的问题:
machine ISOdatetime
1 M1 2013-08-21 18:16:39
2 M1 2013-08-21 18:20:44
3 M1 2013-08-21 18:21:42
4 M1 2013-08-21 18:46:09
5 M1 2013-08-21 18:46:27
6 M1 2013-08-21 19:01:13
etc
我想知道在半小时内发生了多少个值并放入一个新的数据帧,如下所示:
machine ISOdatetime numberobs
1 M1 2013-08-21 18:30:00 3
2 M1 2013-08-21 19:00:00 2
3 M1 2013-08-21 19:30:00 1
etc
以下代码当然适用于整洁的每小时长度:
df2 <- data.frame(table(cut(df$ISOdatetime, breaks="hour")))
以下代码在30分钟的时间内计算,但不会在每小时/每小时点整齐地开始(从第一个列出的时间开始,即18:16:39,并指定从18:16:00开始):
df2 <-data.frame(table(cut(df$ISOdatetime, breaks = "30 mins")))
问题1.什么可能是一个优雅的解决方案?我应该用 ints <-c("18:00", "18:30", "19:00" ...)
之类的东西指定所需的间隔,还是不必要?
问题2.当我到达 df$machine
下"M2"的值的原始数据帧 df
的部分时,我想我也会遇到麻烦,因为它也会计算这些 . 我最终会想要分别绘制每台机器 . 也许为每个"machine"使用 subset
将是一种快速分区数据的方法,但最后我会得到每个"machine"的数据帧 . 不是问题,但是有一种优雅的方法可以在上面的命令中构建"machine"吗?
问题3.在previous post中,他们的计数出现在"top of the hour",这可能是每小时间隔的"end time" . 但是用它们呈现的小数据集检查它并不容易 . 在我自己的数据中,计数似乎已经消失 . 休息时间=小时,我应该期待什么计数?
已阅读并尝试了很多最近几个小时仍然卡住,非常感谢帮助 .
#
根据要求,我添加了更多信息 .
我的实际数据
unit nightof time date isodatetime time2
1 7849 2013-08-21 18:16:39 2013-08-21 2013-08-21 18:16:39 2013-08-22 04:00:00
2 7849 2013-08-21 18:20:44 2013-08-21 2013-08-21 18:20:44 2013-08-22 04:00:00
3 7849 2013-08-21 18:21:42 2013-08-21 2013-08-21 18:21:42 2013-08-22 04:00:00
etc
406 7849 2013-08-21 04:06:10 2013-08-22 2013-08-22 04:06:10 2013-08-22 14:00:00
407 7849 2013-08-21 04:06:12 2013-08-22 2013-08-22 04:06:12 2013-08-22 14:00:00
408 7849 2013-08-21 04:06:28 2013-08-22 2013-08-22 04:06:28 2013-08-22 14:00:00
当我 str()
'data.frame': 408 obs. of 6 variables:
$ unit: int 7849 7849 7849 7849 7849 7849 7849 7849 7849 7849 ...
$ nightof: Date, format: "2013-08-21" "2013-08-21" "2013-08-21" "2013-08-21" ...
$ time: List of 408
..$ : chr "18:16:39"
..$ : chr "18:20:44"
.. [list output truncated]
$ date: Date, format: "2013-08-21" "2013-08-21" "2013-08-21" "2013-08-21" ...
$ isodatetime: POSIXlt, format: "2013-08-21 18:16:39" "2013-08-21 18:20:44" "2013-08-21 18:21:42" "2013-08-21 18:21:48" ...
$ time2: POSIXct, format: "2013-08-22 04:00:00" "2013-08-22 04:00:00" "2013-08-22 04:00:00" "2013-08-22 04:00:00" ...
我使用的修改代码:
`mon$time2 <- with(mon, as.POSIXct(ceiling(as.numeric(isodatetime)/(30*60)) * (30*60), origin = "1970-01-01"))
with(mon, data.frame(table(time2)))
by(mon, mon$unit, function(x){data.frame(table(x$time2))})`
输出 .
mon$unit: 7849
Var1 Freq
1 2013-08-22 04:00:00 27
2 2013-08-22 04:30:00 13
3 2013-08-22 05:00:00 16
4 2013-08-22 05:30:00 5
5 2013-08-22 06:00:00 8
6 2013-08-22 06:30:00 10
7 2013-08-22 07:00:00 25
8 2013-08-22 07:30:00 22
9 2013-08-22 08:00:00 61
10 2013-08-22 08:30:00 93
11 2013-08-22 09:00:00 54
12 2013-08-22 09:30:00 42
13 2013-08-22 10:00:00 11
14 2013-08-22 10:30:00 2
15 2013-08-22 11:00:00 2
16 2013-08-22 11:30:00 3
17 2013-08-22 12:00:00 2
18 2013-08-22 13:00:00 1
19 2013-08-22 14:00:00 11
3 回答
您可以使用
lubridate
包从日期对象中提取小时,分钟等 . 如果你知道活动时间的那一刻,你知道事件发生的半小时 . 我用两台机器采样了一些数据 . 我添加了一个变量的"whole"半小时之后事件发生的地方,然后你可以算这些 . 希望这就是你所追求的,祝你好运 .您可以使用
ceiling
将时间的数字表示舍入为最接近的30分钟:下面是一个旨在生成此类计数的函数 . 以下是其使用示例:
输出是:
参数
categoryCol
(字符)可选地指定包含要对其进行分类的类别的列的名称(每个类别一列) . 列takeOnly
可选地包含一个文本字符串,在数据框data
的环境中进行求值时,会生成一个逻辑向量,用于限制要计数的行 . 有效by
参数的示例包括:"1 day"
,或"1 week"
,或"4 weeks"
,或"1 month"
,或"1 quarter"
,或"1 year"
或"10 years"
. 见help(seq.Date)
.如果确实在基础或推荐的包装中没有这样的功能,我可以提交上述内容,可能需要进行少量修改,以便包含在内 .