【问题标题】:R: Find missing timestamps in csvR:在 csv 中查找缺失的时间戳
【发布时间】:2016-11-30 11:56:16
【问题描述】:

由于数据大小,我未能解决我的 PHP/MySQL 或 Excel 问题,我现在正尝试使用 R 完成我的第一步,并且有点挣扎。问题是这样的:我有一个包含半年数据的逐秒 CSV 文件,看起来像这样:

metering,timestamp
123,2016-01-01 00:00:00
345,2016-01-01 00:00:01
243,2016-01-01 00:00:02
101,2016-01-01 00:00:04
134,2016-01-01 00:00:06

如您所见,每隔一段时间就会丢失几秒钟(不要问我,为什么这些值是在时间戳之前写入的,但这就是我接收数据的方式......)。现在我尝试计算缺失值的数量(= 秒)。

所以我的想法是

  1. 创建一个正确的向量(包括所有逐秒时间戳),
  2. 将给定的 CSV 文件与该新向量匹配,并且
  3. 总结所有没有价值的时间戳。

我设法通过以下代码完成了第 1 步:

RegularTimeSeries <- seq(as.POSIXct("2016-01-01 00:00:00", tz = "UTC"), as.POSIXct("2016-01-01 00:00:30", tz = "UTC"), by = "1 sec")  
write.csv(RegularTimeSeries, file = "RegularTimeSeries.csv")

为了了解我做了什么,我还将向量导出到如下所示的 CSV:

"1",2016-01-01 00:00:00
"2",2016-01-01 00:00:01
"3",2016-01-01 00:00:02
"4",2016-01-01 00:00:03
"5",2016-01-01 00:00:04
"6",2016-01-01 00:00:05
"7",2016-01-01 00:00:06

不幸的是,我不知道如何继续第 2 步和第 3 步。我发现了一些非常相似的示例(http://www.r-bloggers.com/fix-missing-dates-with-r/R: Insert rows for missing dates/times),但作为一个 R 新手,我很难将这些示例转换为我给定的秒以秒为单位的数据。

对新手的一些提示会非常有帮助 - 非常感谢您提前:)

【问题讨论】:

  • 好吧,我想说的是,与其做你的方法,不如用它之前的值减去时间戳。如果大于 1,则输出该值。其他明智的离开它。过段时间会分享代码。
  • 谢谢!是的,用我拥有的数据行减去“应该是”秒是最明显的解决方案(老实说,很明显我没有这个想法)。但无论如何,我的脑海里还有一些进一步的分析,比如找出最长的数据中断发生在哪里,它们在哪里发生了多长时间,等等。为此,无论如何我都需要一个具有“NA”值的数据集。但是对于第一步,您的解决方案当然非常简单:)
  • 我在下面给出了我的代码作为答案,Bene。检查并告诉我是否有帮助

标签: r csv timestamp match


【解决方案1】:

在tidyverse中,

library(dplyr)
library(tidyr)

       # parse datetimes
df %>% mutate(timestamp = as.POSIXct(timestamp)) %>% 
    # complete sequence to full sequence from min to max by second
    complete(timestamp = seq.POSIXt(min(timestamp), max(timestamp), by = 'sec'))

## # A tibble: 7 x 2
##             timestamp metering
##                <time>    <int>
## 1 2016-01-01 00:00:00      123
## 2 2016-01-01 00:00:01      345
## 3 2016-01-01 00:00:02      243
## 4 2016-01-01 00:00:03       NA
## 5 2016-01-01 00:00:04      101
## 6 2016-01-01 00:00:05       NA
## 7 2016-01-01 00:00:06      134

如果你想要NAs 的数量(即没有数据的秒数),添加

%>% tally(is.na(metering))

## # A tibble: 1 x 1
##       n
##   <int>
## 1     2

【讨论】:

  • 非常感谢,这看起来像我正在寻找的东西!不幸的是,它没有产生任何结果——我必须在某处添加一些行吗?我猜“df”是我的原始数据的向量,我可以用df &lt;- read.csv(fpath, header=TRUE, sep=",") 读入,对吧?
  • 你可以使用df &lt;- read.csv(fpath);其他参数已经是默认值。要保存结果,请将它们分配给某些东西,例如df2 &lt;- df %&gt;% mutate(....
【解决方案2】:

您可以使用which%in% 检查您的RegularTimeSeries 的哪些值在损坏的时间序列中。首先从您的示例创建BrokenTimeSeries

RegularTimeSeries <- seq(as.POSIXct("2016-01-01 00:00:00", tz = "UTC"), as.POSIXct("2016-01-01 00:00:30", tz = "UTC"), by = "1 sec")
BrokenTimeSeries <- RegularTimeSeries[-c(3,6,9)] # remove some seconds

这将为您提供RegularTimeSeries 中不在BrokenTimeSeries 中的值的索引:

> which(!(RegularTimeSeries %in% BrokenTimeSeries))
[1] 3 6 9

这将返回实际值:

> RegularTimeSeries[which(!(RegularTimeSeries %in% BrokenTimeSeries))]
[1] "2016-01-01 00:00:02 UTC" "2016-01-01 00:00:05 UTC" "2016-01-01 00:00:08 UTC"

也许我误解了您的问题,但您可以计算丢失的秒数,只需从 RegularTimeSeries 中减去您损坏的时间序列的 length 或获取上述两个结果向量中任何一个的长度。

> length(RegularTimeSeries) - length(BrokenTimeSeries)
[1] 3
> length(which(!(RegularTimeSeries %in% BrokenTimeSeries)))
[1] 3
> length(RegularTimeSeries[which(!(RegularTimeSeries %in% BrokenTimeSeries))])
[1] 3

如果您想将文件合并在一起以查看缺失值,您可以执行以下操作:

#data with regular time series and a "step"
df <- data.frame(
  RegularTimeSeries
)

df$BrokenTimeSeries[RegularTimeSeries %in% BrokenTimeSeries] <- df$RegularTimeSeries
df$BrokenTimeSeries <- as.POSIXct(df$BrokenTimeSeries, origin="2015-01-01", tz="UTC")

导致:

> df[1:12,]
     RegularTimeSeries    BrokenTimeSeries
1  2016-01-01 00:00:00 2016-01-01 00:00:00
2  2016-01-01 00:00:01 2016-01-01 00:00:01
3  2016-01-01 00:00:02                <NA>
4  2016-01-01 00:00:03 2016-01-01 00:00:02
5  2016-01-01 00:00:04 2016-01-01 00:00:03
6  2016-01-01 00:00:05                <NA>
7  2016-01-01 00:00:06 2016-01-01 00:00:04
8  2016-01-01 00:00:07 2016-01-01 00:00:05
9  2016-01-01 00:00:08                <NA>
10 2016-01-01 00:00:09 2016-01-01 00:00:06
11 2016-01-01 00:00:10 2016-01-01 00:00:07
12 2016-01-01 00:00:11 2016-01-01 00:00:08

【讨论】:

  • 这是一篇综合性文章。加一。
【解决方案3】:

如果您想要的只是丢失的秒数,则可以更简单地完成。首先找到时间范围内的秒数,然后减去数据集中的行数。这可以在 R 中按照以下方式完成:

n.seconds <- difftime("2016-06-01 00:00:00", "2016-01-01 00:00:00", units="secs")
n.rows <- nrow(my.data.frame)
n.missing.values <- n.seconds - n.rows

您可以更改数据框的时间范围和变量。

【讨论】:

  • 如果您使用minmax 来计算要减去的时间(并且可能考虑到现有的NAs),这是一个不错的解决方案。
【解决方案4】:

希望对你有帮助

d <- (c("2016-01-01 00:00:01",
"2016-01-01 00:00:02",
"2016-01-01 00:00:03",
"2016-01-01 00:00:04",
"2016-01-01 00:00:05",
"2016-01-01 00:00:06",
"2016-01-01 00:00:10",
"2016-01-01 00:00:12",
"2016-01-01 00:00:14",
"2016-01-01 00:00:16",
"2016-01-01 00:00:18",
"2016-01-01 00:00:20",
"2016-01-01 00:00:22"))
d <- as.POSIXct(d)

for (i in 2:length(d)){
  if(difftime(d[i-1],d[i], units = "secs") < -1 ){
    c[i] <- d[i]
  }
  }
 class(c) <- c('POSIXt','POSIXct')
 c
 [1] NA                        NA                        NA                       
 NA                        NA                       
[6] NA                        "2016-01-01 00:00:10 EST" "2016-01-01 00:00:12    
EST" "2016-01-01 00:00:14 EST" "2016-01-01 00:00:16 EST"
[11] "2016-01-01 00:00:18 EST" "2016-01-01 00:00:20 EST" "2016-01-01    
00:00:22 EST"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    相关资源
    最近更新 更多