【问题标题】:Insert rows for missing time (format HH:MM:SS) in R在 R 中插入缺失时间的行(格式 HH:MM:SS)
【发布时间】:2018-06-20 05:49:24
【问题描述】:

我对 R 相当陌生,并且正在尝试确定是否可以使用 R 来帮助填补我正在使用的大量大型数据集中的缺失值。我会尽力解释。

我正在使用的数据集包含格式为 HH:MM:SS 的时间数据。这是不规则的,因为没有两个数据集具有相同的时间戳,并且时间戳条目记录了 2 小时内的事件。它看起来像这样。

1. Date,         Time_hms, Event
2. 9/22/2015,    00:00:00, 5
3. 9/22/2015,    00:00:24, 1
4. 9/22/2015,    00:00:24, 4
5. 9/22/2015,    00:01:42, 7
6. 9/22/2015,    00:02:04, 3
8. 9/22/2015,    00:02:35, 2
9. 9/22/2015,    00:03:02, 4

我想做的是每隔一分钟添加缺失的行,使其看起来像这样。

1. Date,         Time_hms, Event
2. 9/22/2015,    00:00:00, 5
3. 9/22/2015,    00:00:24, 1
4. 9/22/2015,    00:00:24, 4
5. 9/22/2015,    00:01:00, 4     # Summary row to be inserted
6. 9/22/2015,    00:01:42, 7
7. 9/22/2015,    00:02:00, 7     # Summary row to be inserted
8. 9/22/2015,    00:02:04, 3
9. 9/22/2015,    00:02:35, 2
10. 9/22/2015,   00:03:00, 2     # Summary row to be inserted
11. 9/22/2015,   00:03:02, 4

如果可能,我希望在行中填写在该范围内发生的事件。

在尝试解决这个问题时,我发现并尝试了这种方法Insert rows for missing dates/times。我尝试使用 POSIXct 但由于日期格式而失败。我也考虑过 padr 和 fill_by_function,但不确定这是否是正确的方法。有没有严格使用 HH:MM:SS 格式的方法?

再说一次,我只是在学习 R 并且不确定如何处理这个问题。任何帮助或建议将不胜感激!

编辑:希望我做对了。再次感谢!

dput(elements)
structure(list(var1 = c("Date", "9/22/2015", "9/22/2015", "9/22/2015", 
"9/22/2015", "9/22/2015", "9/22/2015", "9/22/2015"), var2 = c("Time_hms", 
"00:00:00", "00:00:24", "00:00:24", "00:01:42", "00:02:04", "00:02:35", 
"00:03:02"), var3 = c("Event", "5", "1", "4", "7", "3", "2", 
"4")), .Names = c("var1", "var2", "var3"), row.names = c(NA, 
8L), class = "data.frame")

【问题讨论】:

  • 你能通过dput()分享你的样本数据吗?这使得它可以复制/粘贴并保留数据框结构和列类。
  • 至于策略(除非数据集几乎超出您的 RAM 限制):首先,创建一个新数据框,其中只有一列由您的“目标”时间序列填充,其次,加入两个数据框“时间”列
  • 潜在的解决方案是将日期和时间合并到一列,然后使用 POSIXct?但是,之后我必须分开日期和时间。

标签: r time time-series missing-data


【解决方案1】:

好的,您的dput 数据在第一列中有标题。所以我们先解决这个问题:

names(elements) = elements[1, ]
elements = elements[-1, ]
elements$Event = as.numeric(elements$Event)

现在我们将日期和时间转换为 POSIX 日期时间(在一个单独的向量中),然后我们将获取整个数据范围并将其四舍五入到最接近的分钟。然后我们可以创建一个从第一分钟到最后一分钟的序列(并省略日期,使其格式相同):

time_range = round(range(strptime(paste(elements$Date, elements$Time_hms), format = "%m/%d/%Y %H:%M:%S")), units = "mins")
each_minute = seq(from = time_range[1], to = time_range[2], by = "min")
each_minute = format(each_minute, "%H:%M:%S")

最后,我们将merge这些结果返回到原始数据中,对行进行排序,并使用zoo::na.locf用之前的观察值来填补缺失值。

result = merge(elements, data.frame(Time_hms = each_minute), all = T)
result = result[order(result$Time_hms), ]
result$Date = zoo::na.locf(result$Date)
result$Event = zoo::na.locf(result$Event)
result
#    Time_hms      Date Event
# 1  00:00:00 9/22/2015     5
# 2  00:00:24 9/22/2015     1
# 3  00:00:24 9/22/2015     4
# 4  00:01:00 9/22/2015     4
# 5  00:01:42 9/22/2015     7
# 6  00:02:00 9/22/2015     7
# 7  00:02:04 9/22/2015     3
# 8  00:02:35 9/22/2015     2
# 9  00:03:00 9/22/2015     2
# 10 00:03:02 9/22/2015     4

一般来说,特别是如果您的数据可能包含不同日期,您可能会发现如果您只需使用POSIX datetime 对象向您的数据添加一个新列,那么使用起来会更容易。 R 中没有一个很好的类来处理没有日期的时间(至少不是基础 R)——但是你有日期!还有很多函数可以很好地处理日期,比如我在这个答案中使用的seqround

【讨论】:

  • 嗨 Gregor,感谢您抽出宝贵时间帮助我!如果我可以问另一个问题。当测试脚本 > each_minute = seq(from = time_range[1], to = time_range[2], by = "min") 我收到错误消息“Error in seq.int(0, to0 - from, by) : ' to' 必须是有限数”。我假设我犯了一个错误/误解了脚本,并尝试了不同的格式但无法弄清楚。有什么建议吗?
  • @s_meli_m 您可能缺少值。尝试将na.rm = TRUE 添加到range() 调用中。
猜你喜欢
  • 2013-04-02
  • 1970-01-01
  • 2013-05-23
  • 2020-04-12
  • 1970-01-01
  • 2011-10-28
  • 2015-09-17
  • 2021-12-13
  • 2017-07-21
相关资源
最近更新 更多