从时间戳中提取部分信息

3

我有一些数据集,其中动物每5秒钟被记录一次。这些数据存储在postgis中,我正在使用R分析和绘制数据。我想在图表上添加一些标记,显示每小时的位置。我将数据集的子集拉入R中,生成一个数据框,其中包括时间戳和每个点的x和y坐标等信息。

我的数据集大致有10000行,下面是其中一部分的summary():

 id             datetime                        date           
Min.   :2664295   Min.   :2009-08-21 05:00:04   Min.   :2009-08-21  
1st Qu.:2666819   1st Qu.:2009-08-21 08:30:15   1st Qu.:2009-08-21  
Median :2669342   Median :2009-08-21 12:00:03   Median :2009-08-21  
Mean   :2669342   Mean   :2009-08-21 11:30:10   Mean   :2009-08-21  
3rd Qu.:2671866   3rd Qu.:2009-08-21 14:22:44   3rd Qu.:2009-08-21  
Max.   :2674390   Max.   :2009-08-21 16:59:58   Max.   :2009-08-21  

 lokalitet             cowid           x                y          
Length:10          Min.   :553   Min.   :455329   Min.   :6712350  
Class :character   1st Qu.:553   1st Qu.:455718   1st Qu.:6712744  
Mode  :character   Median :553   Median :456154   Median :6713068  
                   Mean   :553   Mean   :456011   Mean   :6713074  
                   3rd Qu.:553   3rd Qu.:456274   3rd Qu.:6713470  
                   Max.   :553   Max.   :456361   Max.   :6713596  

所以,我想要做的是按照日期时间对数据集进行子集选择,其中分钟部分为0,秒部分为<5(即对于摘要中显示的时间戳,我想要的是05:00:04和12:00:03)。(我知道我可以在postgres中做到这一点,但由于基础数据集相当大(约4 M行),并且我没有为部分时间戳建立索引,所以我认为最好在R中对子集进行操作)(不,因为我想要多次执行此操作,所以我不想手动查找匹配的第一行,然后从那里每隔720行取一行)

请提供一个可重现的例子,例如 dput(head(yourData)) - Sven Hohenstein
考虑向 http://sqlfiddle.com/ 添加一些数据,这样我们就可以使用相同的信息进行工作。 - Craig Ringer
3个回答

8
使用lubridate包,从日期中提取分钟和秒钟并进行测试非常容易。例如:
library(lubridate)

## Sample data
dates <- as.POSIXlt(c("2009-08-21 05:00:04","2009-08-21 08:30:15","2009-08-21 12:00:03","2009-08-21 11:30:10","2009-08-21 14:22:44","2009-08-21 16:59:58"))

## How to extract minutes
minute(dates)
# [1]  0 30  0 30 22 59

## How to extract seconds
second(dates)
# [1]  4 15  3 10 44 58

## Select dates from minutes and seconds values
dates[minute(dates)==0 & second(dates) < 5]
# [1] "2009-08-21 05:00:04" "2009-08-21 12:00:03"

2
你可以创建一个辅助函数,接受格式字符串并将其转换为数字。我假设datatimes是POSIXct类型而不是POSIXlt类型。(POSIXct类型与数据框操作不兼容。)
ndtfrm <- function(dt, frm) as.numeric(format(dt, frm))
ndtfrm(dates, "%M")
#[1]  0 30  0 30 22 59
ndtfrm(dates, "%S")
#[1]  4 15  3 10 44 58

 dfrm[ ndtfrm(dfrm$dates, "%M") ==0 & ndtfrm(dfrm$dates, "%S") < 5 , ]

0
感谢您的回答,但事实证明在PostgreSQL中最容易完成它...
一个简单的。
SELECT ..., case when extract(second from datetime)<5 
                         and extract(minute from datetime) = 28 
  then extract(hour from datetime) end as marker  FROM ....

这个给了我所需的 - 而且因为我只是在和整个数据集一起取回这些数据,所以无需搜索这些点。


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