按R中的时间间隔对数据进行分区

时间:2012-07-06 20:22:07

标签: r dataset partitioning

我按小时观察了一些数据。我试图按天或甚至周间隔对这些数据进行子集化。我不确定如何在R中继续执行此任务。

数据样本如下。

date                                 obs
2011-10-24 01:00:00                  12
2011-10-24 02:00:00                  4
2011-10-24 19:00:00                  18
2011-10-24 20:00:00                  7
2011-10-24 21:00:00                  4
2011-10-24 22:00:00                  2
2011-10-25 00:00:00                  4
2011-10-25 01:00:00                  2
2011-10-25 02:00:00                  2
2011-10-25 15:00:00                  12
2011-10-25 18:00:00                  2
2011-10-25 19:00:00                  3
2011-10-25 21:00:00                  2
2011-10-25 23:00:00                  9
2011-10-26 00:00:00                  13
2011-10-26 01:00:00                  11

2 个答案:

答案 0 :(得分:2)

我会使用时间序列类,例如xts

dat <- read.table(text="2011-10-24 01:00:00                  12
2011-10-24 02:00:00                  4
2011-10-24 19:00:00                  18
2011-10-24 20:00:00                  7
2011-10-24 21:00:00                  4
2011-10-24 22:00:00                  2
2011-10-25 00:00:00                  4
2011-10-25 01:00:00                  2
2011-10-25 02:00:00                  2
2011-10-25 15:00:00                  12
2011-10-25 18:00:00                  2
2011-10-25 19:00:00                  3
2011-10-25 21:00:00                  2
2011-10-25 23:00:00                  9
2011-10-26 00:00:00                  13
2011-10-26 01:00:00                  11", header=FALSE, stringsAsFactors=FALSE)

xobj <- xts(dat[, 3], as.POSIXct(paste(dat[, 1], dat[, 2])))

xts子集非常直观。对于“2011-10-25”的所有数据,请执行此操作

xobj["2011-10-25"]
#                    [,1]
#2011-10-25 00:00:00    4
#2011-10-25 01:00:00    2
#2011-10-25 02:00:00    2
#2011-10-25 15:00:00   12
#2011-10-25 18:00:00    2
#2011-10-25 19:00:00    3
#2011-10-25 21:00:00    2
#2011-10-25 23:00:00    9

您也可以将这样的时间跨度进行分组(2011-10-24和2011-10-25之间的所有数据)

xobj["2011-10-24/2011-10-25"]

或者,如果您想要2011年10月的所有数据,

xobj["2011-10"]

如果您想从19:00到20:00之间的任何一天获取所有数据,

xobj['T19:00:00/T20:00:00']
#                    [,1]
#2011-10-24 19:00:00   18
#2011-10-24 20:00:00    7
#2011-10-25 19:00:00    3

您可以使用endpoints功能查找一段时间段的最后一行(“小时”,“天”,“周”等)。

endpoints(xobj, "days")
[1]  0  6 14 16    

或者您可以转换为较低的频率

to.weekly(xobj)
#           xobj.Open xobj.High xobj.Low xobj.Close
#2011-10-26        12        18        2         11
to.daily(xobj)
#           xobj.Open xobj.High xobj.Low xobj.Close
#2011-10-25        12        18        2          2
#2011-10-26         4        12        2          9
#2011-10-26        13        13       11         11

请注意,上面创建了Open,High,Low和Close列。如果您只想要端点上的数据,可以使用OHLC=FALSE

to.daily(xobj, OHLC=FALSE)
#           [,1]
#2011-10-25    2
#2011-10-26    9
#2011-10-26   11

有关更基本的子集等等,请访问http://www.quantmod.com/examples/

正如@JoshuaUlrich在评论中提到的那样,split.xts非常有用。

您可以按天(或周,或月等)拆分,应用函数,然后重新组合

split(xobj, 'days') #create a list where each element is the data for a different day
#[[1]]
#                    [,1]
#2011-10-24 01:00:00   12
#2011-10-24 02:00:00    4
#2011-10-24 19:00:00   18
#2011-10-24 20:00:00    7
#2011-10-24 21:00:00    4
#2011-10-24 22:00:00    2
#
#[[2]]
#                    [,1]
#2011-10-25 00:00:00    4
#2011-10-25 01:00:00    2
#2011-10-25 02:00:00    2
#2011-10-25 15:00:00   12
#2011-10-25 18:00:00    2
#2011-10-25 19:00:00    3
#2011-10-25 21:00:00    2
#2011-10-25 23:00:00    9
#
#[[3]]
#                    [,1]
#2011-10-26 00:00:00   13
#2011-10-26 01:00:00   11

假设您只想要每天的第一个值。 splitlapply first函数和rbind重新组合在一起。

do.call(rbind, lapply(split(xobj, 'days'), first))
#                    [,1]
#2011-10-24 01:00:00   12
#2011-10-25 00:00:00    4
#2011-10-26 00:00:00   13

答案 1 :(得分:1)

首先我输入了数据,其中多个空格被替换为标签。

dat$date <- as.POSIXct(dat$date, format="%Y-%m-%d %H:%M:%S")
split(dat , as.POSIXlt(dat$date)$yday)
# Notice these are not the same functions
#---------------------
$`296`
                 date obs
1 2011-10-24 01:00:00  12
2 2011-10-24 02:00:00   4
3 2011-10-24 19:00:00  18
4 2011-10-24 20:00:00   7
5 2011-10-24 21:00:00   4
6 2011-10-24 22:00:00   2

$`297`
                  date obs
7  2011-10-25 00:00:00   4
8  2011-10-25 01:00:00   2
9  2011-10-25 02:00:00   2
10 2011-10-25 15:00:00  12
11 2011-10-25 18:00:00   2
12 2011-10-25 19:00:00   3
13 2011-10-25 21:00:00   2
14 2011-10-25 23:00:00   9

$`298`
                  date obs
15 2011-10-26 00:00:00  13
16 2011-10-26 01:00:00  11

POSIXlt类在数据框架内不能很好地工作,但它对于创建基于时间的组非常方便。这是一个带有这些指数的列表结构:'yday','wday','year','mon','mday','hour','min','sec'和'isdt'。 cut.POSIXt函数在其他自然边界处添加了划分; E.g。

?cut.POSIXt
  split(dat , cut(dat$date, "week") )

如果你想在日期内总结:

tapply(dat$obs, as.POSIXlt(dat$date)$yday, sum)
#-------
296 297 298 
 47  36  24