仅识别第一个匹配的记录

时间:2014-01-31 22:13:29

标签: r date datetime

我有大量的时间序列数据存储在名为“Tag.data”的数据框中,其中一个记录在几个月的过程中每30秒拍摄一次。例如:

  • 2013-09-30 23:59:00
  • 2013-09-30 23:59:30
  • 2013-10-01 00:00:00
  • 2013-10-01 00:00:30
  • 2013-10-01 00:01:00
  • 2013-10-01 00:01:30
  • 2013-10-01 00:02:00
  • ...
  • 2013-10-15 05:00:00
  • 2013-10-15 05:00:30
  • 2013-10-15 05:01:00
  • 2013-10-15 05:01:30
  • 2013-10-15 05:02:00
  • ...

此数据存储在Tag.data $ dt。

在我的数据中,我想确定每个月的第1天和第15天,以便这些可以在以后的情节中使用。

我成功地使用以下代码识别每个月的第一天:

locs <- tapply (X=Tag.data$dt, FUN=min, INDEX=format(Tag.data$dt, '%Y%m'))
at <- Tag.data$dt %in% locs
at <- at & format(Tag.data$dt, '%m') %in% c('01', '02', '03','04', '05', '06','07', '08', '09','10', '11', '12') & format(Tag.data$dt, '%d') == '01'

不幸的是,当我尝试使用此代码识别每个月的第15天时,我的成功率较低:

locs <- tapply (X=Tag.data$dt, FUN=min, INDEX=format(Tag.data$dt, '%Y%m'))
at <- Tag.data$dt %in% locs
at <- at & format(Tag.data$dt, '%m') %in% c('01', '02', '03','04', '05', '06','07', '08', '09','10', '11', '12') & format(Tag.data$dt, '%d') == '01'| 
format(Tag.data$dt, '%m') %in% c('01', '02', '03','04', '05', '06','07', '08', '09','10', '11', '12') & format(Tag.data$dt, '%d') == '15'

虽然这确实确定了每个月的第1天和第15天,但由于某种原因,它仅确定了该月第1天的一个记录,但是该月的第15天的每个记录(其中有一个很好的记录)许多)。我想确定每个月的第1天和第15天的第一个记录。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

从您的代码判断:

locs <- tapply (X=Tag.data$dt, FUN=min, INDEX=format(Tag.data$dt, '%Y%m'))

我认为Tag.data$dt存储为POSIX类之一。

  

我只想确定每个月的第1天和第15天的第一张记录。

可能很慢,但是这样做了。

ymd <- format(Tag.data$dt,"%Y%m%d")
index.01.15 <- !duplicated(ymd) & grepl("01$|15$", ymd)

您可以使用逻辑向量选择行Tag.data[index.01.15, ]

答案 1 :(得分:0)

试试这个。它利用了润滑剂。您可以选择日期为1或15的所有行。

library(lubridate)
options(stringsAsFactors=FALSE)

Tag.data = structure(list(dt = c("30/09/2013 23:59", "1/10/2013 0:00", "1/10/2013 0:00", 
"1/10/2013 0:01", "1/10/2013 0:01", "1/10/2013 0:02", "2/10/2013 0:04", 
"15/10/2013 5:00", "15/10/2013 5:00", "15/10/2013 5:01", "15/10/2013 5:01", 
"15/10/2013 5:02")), .Names = "dt", class = "data.frame", row.names = c(NA, 
-12L))


Tag.data$dt = parse_date_time(Tag.data$dt, '%d/%m/%Y %H%M')
at = Tag.data[day(Tag.data$dt) %in% c(1,15), ]

这更灵活,因为您可以指定任何您希望子集的日期。例如,将c(1,15)中的值替换为任何一天,或month(Tag.data$dt) %in% c(<INSERT MONTH NUMBER>)替换为月份的子集。

答案 2 :(得分:0)

您的数据看起来已经存储为某种日期(例如,POSIXct)。这样的东西,但有更多的行?

Tag.data <- data.frame(dt=seq(ISOdate(2013,10,1), by = "30 min", length.out = 10000))

然后,如果您只需要每个第1天或第15天的第一条记录,这可能会有效:

daychars <- format(Tag.data$dt, '%d')
day1or15 <- daychars %in% c("01","15")
newday <- c(TRUE, (daychars[1:(length(daychars)-1)] != daychars[2:length(daychars)]))
format(Tag.data[day1or15 & newday,"dt"],"%m/%d/%Y %H:%M:%S")

newday行有助于不要在任何特定时间开始这一天,但它确实假定您的时间序列已订购。

答案 3 :(得分:0)

我建议您在xts中使用优秀的R包来计算时间序列数据。

您没有提供可重复的数据,所以我自己做了一些。

require(xts)
Tag.data <- xts(rnorm(1e5), order.by = Sys.time() + seq(30, 3e6, 30))

按月份的日期设置是一个简单的单行。

days_1n15 <- Tag.data[.indexmday(Tag.data) %in% c(1, 15)]

这将返回任何月份的第1天和第15天的所有记录。

现在我们只需要在每个匹配日抽出第一个观察结果。

firstOf <- do.call(rbind, lapply(split(days_1n15, 'days'), first))

其中包含您想要的数据:

R> firstOf
                         [,1]
2014-02-01 21:29:01  1.284222
2014-02-15 00:00:01 -1.262235
2014-03-01 00:00:01 -0.465001