使用grepl&;使用时间序列数据验证准确的字符串拆分

使用grepl&;使用时间序列数据验证准确的字符串拆分,r,validation,time-series,grepl,R,Validation,Time Series,Grepl,我正在处理1分钟太阳能光伏间隔时间序列数据,其中原始时间戳将日期和时间连接在一起。我使用sub()拆分日期和时间,然后使用cbind()将它们添加到数据帧中。乍一看,一切似乎都很好,但我想建立一个小的错误检查,确保日期和时间匹配原始字符串,如果他们不匹配,那么它将返回行索引供我进一步排除故障。我的想法是使用grepl+来识别匹配/不匹配。下面的代码显示了我正在使用的内容 > head(data2) dates times datetime use..kW. g

我正在处理1分钟太阳能光伏间隔时间序列数据,其中原始时间戳将日期和时间连接在一起。我使用sub()拆分日期和时间,然后使用cbind()将它们添加到数据帧中。乍一看,一切似乎都很好,但我想建立一个小的错误检查,确保日期和时间匹配原始字符串,如果他们不匹配,那么它将返回行索引供我进一步排除故障。我的想法是使用grepl+来识别匹配/不匹配。下面的代码显示了我正在使用的内容

> head(data2)
   dates times         datetime use..kW.     gen..kW. Grid..kW.
1 12/31/2013 23:58 12/31/2013 23:58 1.463883 -0.003050000  1.463883
2 12/31/2013 23:57 12/31/2013 23:57 1.940267 -0.003450000  1.940267
3 12/31/2013 23:56 12/31/2013 23:56 1.934417 -0.003466667  1.934417
4 12/31/2013 23:55 12/31/2013 23:55 1.996050 -0.003550000  1.996050
5 12/31/2013 23:54 12/31/2013 23:54 2.009883 -0.003566667  2.009883
6 12/31/2013 23:53 12/31/2013 23:53 2.009967 -0.003516667  2.009967
Solar..kW. Solar...kW.
1 -0.003050000           0
2 -0.003450000           0
3 -0.003466667           0
4 -0.003550000           0
5 -0.003566667           0
6 -0.003516667           0

> a <- grepl("23:56", data2[, 3])

> which(a == TRUE)
  [1]      3   1443   2883   4323   5763   7203   8643  10083  11523
我使用了相同的mapply函数,只对一系列的观察结果(200)。当设置为TRUE时,我得到200行的索引,如果设置为FALSE,我得到整数(0)-我理解这意味着我的数据是准确的,所以所有这些可能都是不必要的。。。但现在我更多地从学习/锻炼的角度来研究这个问题,这将有助于我处理更大的数据集

抱歉问了这么长的问题。提前感谢您的建议

第2部分:

我很抱歉没有提供可复制的数据。我的数据太大,无法将整个数据帧发布到SO。另外@G.Grothendieck,我正在拆分datetime字符串,因为我将使用tapply或split来获取每个时间间隔的采样分布,也就是说,我将有1440个“桶”,对应于一天中的每分钟。每一个桶都将充满全年在该时间间隔的观测数据

这里有一个新版本(data3),它是data2的头。我已将data3[3,2]的值更改为“23:57”,这与datatime列中的时间不匹配,因此我们可以使用它来测试两个解决方案。贾斯汀的排在第一位,其次是G·格罗森迪克

> data3 <- head(data2)
> data3[3,2] <- "23:57"
> data3
       dates times         datetime use..kW.     gen..kW. Grid..kW.   Solar..kW.
1 12/31/2013 23:58 12/31/2013 23:58 1.463883 -0.003050000  1.463883 -0.003050000
2 12/31/2013 23:57 12/31/2013 23:57 1.940267 -0.003450000  1.940267 -0.003450000
3 12/31/2013 23:57 12/31/2013 23:56 1.934417 -0.003466667  1.934417 -0.003466667
4 12/31/2013 23:55 12/31/2013 23:55 1.996050 -0.003550000  1.996050 -0.003550000
5 12/31/2013 23:54 12/31/2013 23:54 2.009883 -0.003566667  2.009883 -0.003566667
6 12/31/2013 23:53 12/31/2013 23:53 2.009967 -0.003516667  2.009967 -0.003516667
  Solar...kW.
1           0
2           0
3           0
4           0
5           0
6           0
> all(paste(data3$dates, data3$times) == data3$datetime)
[1] FALSE
> which(paste(data3$dates, data3$times) != data3$datetime)
[1] 3
> with(data3, which(format(datetime) != paste(dates, times)))
[1] 3
我将不匹配的前6行放入一个新的df(data4)。然后再次应用每个解决方案

> data4
         dates times        datetime use..kW. gen..kW.  Grid..kW. Solar..kW.
840 12/31/2013  9:59 12/31/2013 9:59 4.480733 5.948300 -1.4675667   5.948300
841 12/31/2013  9:58 12/31/2013 9:58 4.503950 5.832533 -1.3285833   5.832533
842 12/31/2013  9:57 12/31/2013 9:57 4.516283 5.739600 -1.2233167   5.739600
843 12/31/2013  9:56 12/31/2013 9:56 4.906783 5.677033 -0.7702500   5.677033
844 12/31/2013  9:55 12/31/2013 9:55 5.951183 5.621617  0.3295667   5.621617
845 12/31/2013  9:54 12/31/2013 9:54 6.226417 5.596517  0.6299000   5.596517
    Solar...kW.
840    5.948300
841    5.832533
842    5.739600
843    5.677033
844    5.621617
845    5.596517
> all(paste(data4$dates, data4$times) == data4$datetime)
[1] TRUE
> which(paste(data4$dates, data4$times) != data4$datetime)
integer(0)
> with(data4, which(format(datetime) != paste(dates, times)))
integer(0)
> 

这再次表明,您的解决方案是相同的,但我不明白为什么在整个数据帧(data2)上使用G.Grothendieck的,为什么它输出840:24279作为不匹配。让我知道这些数据是否足够

您可以使用矢量化布尔比较

all(paste(data2$dates, data2$times) == data2$datetime)
如果所有内容都匹配,则应返回
TRUE
,否则返回
FALSE
。您还可以将其包装在
中,然后使用
=以查看内容不匹配的行

which(paste(data2$dates, data2$times) != data2$datetime)
最后,我尽量避免使用正则表达式(和
sub
)。相反,我会使用如下内容:

splits <- strsplit(data2$datetime, ' ')
data2$dates <- sapply(splits, '[', 1)
data2$times <- sapply(splits, '[', 2)

拆分这将给出
日期
时间
与日期时间不匹配的行号

with(data2, which(format(datetime) != paste(date, time)))
您可能不需要
格式
部分,但我们无法确定,因为问题中没有以可复制的形式提供数据


也要考虑一下,你是否真的需要首先分开<代码> DATETIME>/代码>。

我不明白你在那里做什么。为什么不把日期时间转换成POSIXct呢?如果基本函数不能提供满足您需求的足够功能,您甚至可以使用包lubridate。让我重申一下:您不需要拆分日期时间,也不应该使用模式匹配。R附带了处理日期时间的特定函数,使用这些函数以及可能的时间序列包,您可以轻松地完成所有您想做的事情。罗兰,感谢您的输入。我现在明白了为什么使用正则表达式不是最好的。我将我的datetime转换为POSIXct,现在正试图弄清楚如何:(1)只对“白天”观测值进行子集,即在7:00和21:00之间(2)将数据子集/拆分为5分钟和15分钟的间隔。这真的不符合我原来的问题,所以我可能很快会发表另一篇文章。太好了,谢谢!这太棒了。我想真的没有必要在每一行上循环。@stokeinfo-FWIW,几乎没有必要在每一行上循环!这个解决方案让我很害怕,因为它说413000个观测值不匹配。贾斯汀的上述解决方案产生了一个真实的结果,似乎表明一切正常。对这两种解决方案之间的差异有何看法?在提出问题时,您确实需要以可复制的形式提供数据。没有这些,我们只是猜测。例如,格式可能产生时区?尝试发布
dput(head(data2))
。此外,如前所述,真正的解决方案可能是datetime一开始就不应该被分割。我会支持@G.Grothendieck所说的一切!在我们知道你的数据到底是什么样子之前,这一切都是无中生有的。数据太大了,不适合发布。因为我是一个新的SO用户,所以我必须开始一个新问题以继续进行故障排除。不,不是。你已经贴了。我们只是要求您以可复制的形式发布:
dput(head(data2))
。另外,请说明为什么需要拆分日期时间。
splits <- strsplit(data2$datetime, ' ')
data2$dates <- sapply(splits, '[', 1)
data2$times <- sapply(splits, '[', 2)
with(data2, which(format(datetime) != paste(date, time)))