如何在R中对日期时间数据进行子集化并透视度量列

6
我有一个类似于这样的数据框:
Datetime <- c("2015-12-31 08:30:13", "2015-12-31 12:45:00", "2016-01-01 02:53:20", "2016-01-01 03:22:18", 
              "2016-01-01 09:42:10", "2016-01-01 20:55:50", "2016-01-01 21:14:10", "2016-01-02 05:42:16",
              "2016-01-02 08:31:15", "2016-01-02 09:13:10", "2016-01-03 00:45:14", "2016-01-03 05:56:00", 
              "2016-01-03 13:44:00", "2016-01-03 14:41:20", "2016-01-03 15:33:10", "2016-01-04 04:24:00",
              "2016-01-04 17:24:12", "2016-01-04 17:28:16", "2016-01-04 18:22:34", "2016-01-05 02:34:31")

Measurement <- c("Length","Breadth","Height","Length",
                 "Breadth","Breadth","Breadth","Length",
                 "Length","Breadth","Height","Height",
                 "Height","Length","Height","Length",
                 "Length","Breadth","Breadth","Breadth")

df1 <- data.frame(Datetime,Measurement)

我将尝试对这种格式的日期进行子集划分

Day1 = December 31st,2015 at 6:30AM to January 1st 2016 6:30AM
Day2 = January 1st,2015 at 6:30AM to January 2nd 2016 6:30AM

etc..

在此过程中,我还希望将“Measurement”列旋转为其各个类别的单独列,并计算每个类别的数量。 我的期望输出结果为:
Days Length Breadth Height
Day1      2       1      1
Day2      1       3      0
Day3      1       1      2
Day4      2       0      2
Day5      1       3      0

我尝试了类似以下的方法来获取日期范围。
today <- as.POSIXlt(Sys.time())
today$mday <- today$mday + (today$wday-(today$wday+27)) 
today$hour = "6";today$min = "30";today$sec = "0"
Back1Day <- today 
Back1Day$mday <- today$mday-1

如何根据这个问题进行子集。我尝试使用dcast进行操作,但是没有成功。

df2 <- dcast(df1, Datetime ~ Measurement)

请提供一些关于此事的指导。

“2015-12-31 02:53:20” 所属的确切日期不是很清楚。 - David Arenburg
David,谢谢你指出来。很抱歉我在那里犯了一个错误,我刚刚编辑了它“2016-01-01 02:53:20”。 - Sharath
第一天始终是在早上6:30之后开始吗?否则它应该属于您日期范围之前的一天。 - David Arenburg
是的。例如:为了计算1月1日的测量次数,我查看这个日期范围(12月31日6:30到1月1日6:30)。这是我在更大的数据集中使用的逻辑。 - Sharath
1个回答

7

根据您的评论,这似乎符合您的需求。我只是通过按天从第一个日期到最后一个创建一个序列,然后利用findInterval函数来匹配日期。然后,简单的dcast就可以给您所需的结果。

library(data.table)
setDT(df1)[, Datetime := as.POSIXct(Datetime)] ## First need to convert to POSIXct class
df1[, Days := paste0("Day", findInterval(Datetime, 
                              seq(as.POSIXct(paste(as.Date(Datetime[1L]), "6:30")), 
                                  as.POSIXct(paste(as.Date(Datetime[.N]), "6:30")), 
                             by = "day")))]
dcast(df1, Days ~ Measurement)
#    Days Breadth Height Length
# 1: Day1       1      1      2
# 2: Day2       3      0      1
# 3: Day3       1      2      1
# 4: Day4       0      2      2
# 5: Day5       3      0      1

1
太棒了!!在我的更大数据集上也像魔法一样运行得很好,速度也非常快 :-) 非常感谢你,David。 - Sharath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接