-1

我正在使用 1 分钟太阳能 PV 间隔时间序列数据,其中原始时间戳将日期和时间连接在一起。我使用 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

上面 which() 的结果对应于 datetime 列中字符串中所有带有“23:56”的行。我只复制了一行返回向量以节省空间...

我知道对于我的检查器,我想识别虚假案例,现在使用 TRUE 只是为了说明。我遇到的问题与在 grepl() 中使用多个字符串有关,因为我不只是想使用一个时间值来执行此操作,而是针对我的数据框中的每一行。我尝试将 mapply 与 grepl 一起使用,但我的数据框有 478,933 个观察值,因此需要很长时间。mapply + grepl 看起来像:

mapply(grepl, data2$dates, data2$datetime)

我已经使用了相同的 mapply 函数,只有一系列观察值(200)。当设置为 TRUE 时,我得到 200 行的索引,使用 FALSE 我得到 integer(0) - 我理解这意味着我的数据是准确的,所以这一切可能都是不必要的......但现在我从更多的是学习/练习的观点,它将使我在处理更大的数据集时受益。

抱歉问了一个很长的问题。提前感谢您的建议。

第2部分:

我很抱歉没有提供可重复的数据。我的数据太大,无法将整个数据框发布到 SO。另外@G.Grothendieck,我正在拆分日期时间字符串,因为我将使用tapply 或split 来获取每个时间间隔的采样分布,即我将有1,440 个“桶”对应于一天中的每一分钟。每个桶将由全年的该时间间隔内的观察结果填充。

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

> 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

所以,它们都导致相同的结果......但是,当我在整个数据帧(data2)上使用 G.Grothendieck 的解决方案时,它说第 840:24279 行不匹配。这是输出的前两行:

> with(data2, which(format(datetime) != paste(dates, times)))
    [1]   840   841   842   843   844   845   846   847   848   849   850   851
   [13]   852   853   854   855   856   857   858   859   860   861   862   863

我将不匹配的前 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 是不匹配的。让我知道这些数据是否足够。

4

2 回答 2

0

This will give the row numbers where the date and time do not match the datetime

with(data2, which(format(datetime) != paste(date, time)))

You might not need the format part but we can't tell since the data was not provided in a reproducible form in the question.

Also, consider whether you really need to split datetime up in the first place.

于 2014-02-07T18:09:49.740 回答
0

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

all(paste(data2$dates, data2$times) == data2$datetime)

TRUE如果一切匹配,则应返回,FALSE否则返回。您也可以将其包装起来which并使用它!=来查看不匹配的行。

which(paste(data2$dates, data2$times) != data2$datetime)

最后,我尽可能避免使用正则表达式 (and sub)。相反,我会使用这样的东西:

splits <- strsplit(data2$datetime, ' ')
data2$dates <- sapply(splits, '[', 1)
data2$times <- sapply(splits, '[', 2)
于 2014-02-07T18:07:57.470 回答