【问题标题】:Amend missing times to datetime series in R将缺失时间修改为 R 中的日期时间序列
【发布时间】:2019-09-19 01:33:18
【问题描述】:

我有一个每小时时间序列的日期时间,格式为“%Y-%m-%d %H:%M:%S”和“字符”类。目标是使用 as.POSIXct 将字符数据转换为日期和时间。但是,尽管每个日期的记录数 (24) 是正确的,但时间序列中的某些记录缺少时间部分(“%H:%M:%S”)。

是否可以用从 00:00:00 开始到每个日期的 23:00:00 结束的小时序列来填写这些记录的时间部分?

原始数据集:

Date_time 
...
1991-03-31 21:00:00
1991-03-31 22:00:00 
1991-03-31 23:00:00
1991-04-01
1991-04-01
1991-04-01
...

我想要什么:

Date_time 
...
1991-03-31 21:00:00
1991-03-31 22:00:00 
1991-03-31 23:00:00
1991-04-01 00:00:00
1991-04-01 01:00:00
1991-04-01 02:00:00
...

我得到的最接近的解决方法是仍然采用字符格式,但结果从 16:00:00 开始。请发送暂停。

hours=c("00:00:00", "01:00:00", "02:00:00", "03:00:00", "04:00:00", "05:00:00", "06:00:00", "07:00:00", "08:00:00", "09:00:00", "10:00:00", "11:00:00", "12:00:00","13:00:00", "14:00:00", "15:00:00", "16:00:00", "17:00:00", "18:00:00", "19:00:00", "20:00:00","21:00:00", "22:00:00", "23:00:00")

Dataset %>%
  mutate(Date_time_filled = ifelse(nchar(as.character(Date_time))<19, 
                                   paste(Date_time, hours), 
                                   paste(Date_time)))

我得到了什么(错误):

Date_time 
...
1991-03-31 21:00:00
1991-03-31 22:00:00 
1991-03-31 23:00:00
1991-04-01 16:00:00
1991-04-01 17:00:00
1991-04-01 18:00:00
...

编辑:

 X metadata.id metadata.name metadata.lat metadata.lon              Date_time data.v data.s data.f
1   1     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 01:00:00     NA     NA    1,1
2   2     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 02:00:00     NA     NA    1,1
3   3     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 03:00:00     NA     NA    1,1
4   4     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 04:00:00     NA     NA    1,1
5   5     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 05:00:00     NA     NA    1,1
6   6     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 06:00:00     NA     NA    1,1
7   7     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 07:00:00     NA     NA    1,1
8   8     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 08:00:00     NA     NA    1,1
9   9     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 09:00:00     NA     NA    1,1
10 10     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 10:00:00     NA     NA    1,1
11 11     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 11:00:00     NA     NA    1,1
12 12     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 12:00:00     NA     NA    1,1
13 13     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 13:00:00     NA     NA    1,1
14 14     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 14:00:00     NA     NA    1,1
15 15     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 15:00:00     NA     NA    1,1
16 16     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 16:00:00     NA     NA    1,1
17 17     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 17:00:00     NA     NA    1,1
18 18     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 18:00:00     NA     NA    1,1
19 19     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 19:00:00     NA     NA    1,1
20 20     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 20:00:00     NA     NA    1,1
21 21     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 21:00:00     NA     NA    1,1
22 22     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 22:00:00     NA     NA    1,1
23 23     9411340 Santa Barbara      34.4031    -119.6928 1990-10-22 23:00:00     NA     NA    1,1
24 24     9411340 Santa Barbara      34.4031    -119.6928 1990-10-23 00:00:00     NA     NA    1,1
25 25     9411340 Santa Barbara      34.4031    -119.6928 1990-10-23 01:00:00     NA     NA    1,1

【问题讨论】:

    标签: r datetime posixct


    【解决方案1】:

    不确定这是否是您正在寻找的,或者它至少可以让您走上正轨:

    # This is the working horse:
    seq(as.POSIXct("1991-03-31 00:00:00"), as.POSIXct("1991-04-02 23:00:00"), by = "1 hour")
    
     [1] "1991-03-31 00:00:00 -05" "1991-03-31 01:00:00 -05" "1991-03-31 02:00:00 -05" "1991-03-31 03:00:00 -05" "1991-03-31 04:00:00 -05"
     [6] "1991-03-31 05:00:00 -05" "1991-03-31 06:00:00 -05" "1991-03-31 07:00:00 -05" "1991-03-31 08:00:00 -05" "1991-03-31 09:00:00 -05"
    [11] "1991-03-31 10:00:00 -05" "1991-03-31 11:00:00 -05" "1991-03-31 12:00:00 -05" "1991-03-31 13:00:00 -05" "1991-03-31 14:00:00 -05"
    [16] "1991-03-31 15:00:00 -05" "1991-03-31 16:00:00 -05" "1991-03-31 17:00:00 -05" "1991-03-31 18:00:00 -05" "1991-03-31 19:00:00 -05"
    [21] "1991-03-31 20:00:00 -05" "1991-03-31 21:00:00 -05" "1991-03-31 22:00:00 -05" "1991-03-31 23:00:00 -05" "1991-04-01 00:00:00 -05"
    [26] "1991-04-01 01:00:00 -05" "1991-04-01 02:00:00 -05" "1991-04-01 03:00:00 -05" "1991-04-01 04:00:00 -05" "1991-04-01 05:00:00 -05"
    [31] "1991-04-01 06:00:00 -05" "1991-04-01 07:00:00 -05" "1991-04-01 08:00:00 -05" "1991-04-01 09:00:00 -05" "1991-04-01 10:00:00 -05"
    [36] "1991-04-01 11:00:00 -05" "1991-04-01 12:00:00 -05" "1991-04-01 13:00:00 -05" "1991-04-01 14:00:00 -05" "1991-04-01 15:00:00 -05"
    [41] "1991-04-01 16:00:00 -05" "1991-04-01 17:00:00 -05" "1991-04-01 18:00:00 -05" "1991-04-01 19:00:00 -05" "1991-04-01 20:00:00 -05"
    [46] "1991-04-01 21:00:00 -05" "1991-04-01 22:00:00 -05" "1991-04-01 23:00:00 -05" "1991-04-02 00:00:00 -05" "1991-04-02 01:00:00 -05"
    [51] "1991-04-02 02:00:00 -05" "1991-04-02 03:00:00 -05" "1991-04-02 04:00:00 -05" "1991-04-02 05:00:00 -05" "1991-04-02 06:00:00 -05"
    [56] "1991-04-02 07:00:00 -05" "1991-04-02 08:00:00 -05" "1991-04-02 09:00:00 -05" "1991-04-02 10:00:00 -05" "1991-04-02 11:00:00 -05"
    [61] "1991-04-02 12:00:00 -05" "1991-04-02 13:00:00 -05" "1991-04-02 14:00:00 -05" "1991-04-02 15:00:00 -05" "1991-04-02 16:00:00 -05"
    [66] "1991-04-02 17:00:00 -05" "1991-04-02 18:00:00 -05" "1991-04-02 19:00:00 -05" "1991-04-02 20:00:00 -05" "1991-04-02 21:00:00 -05"
    [71] "1991-04-02 22:00:00 -05" "1991-04-02 23:00:00 -05"
    

    可以这样使用:

    Dataset$date_time_filled <- seq(as.POSIXct(Dataset$date_time[1]),
                                    as.POSIXct(Dataset$date_time[nrow(Dataset)]), 
                                    by = "1 hour")
    

    如果date_time 的最后一次读数错过了时间,它会起作用,但会认为最后一次读数好像发生在 00:00:00,因此可能由于向量长度不同而出错。您可能需要手动调整。

    【讨论】:

    • 感谢@PavoDive。我想我确实有一些不同的向量长度使事情复杂化。请看下面我的回答。再次感谢。
    【解决方案2】:

    由于您已经为每个日期提供了许多记录,并且仅缺少时间部分,因此一种方法是使用 sprintf 并复制每个日期的时间部分。

    library(dplyr)
    
    df %>%
      mutate(Date_time1 = as.POSIXct(Date_time), 
             Date_time1 = paste(Date_time1, sprintf("%02d:00:00", 0:23)))
    

    在小子集上尝试这个 0 到 5 小时。

    library(dplyr)
    df %>%
      mutate(Date_time1 = as.POSIXct(Date_time), 
             Date_time1 = paste(Date_time1, sprintf("%02d:00:00", 0:5)))
    
    
    #             Date_time          Date_time1
    #1  1991-03-31 00:00:00 1991-03-31 00:00:00
    #2  1991-03-31 01:00:00 1991-03-31 01:00:00
    #3  1991-03-31 02:00:00 1991-03-31 02:00:00
    #4  1991-03-31 03:00:00 1991-03-31 03:00:00
    #5  1991-03-31 04:00:00 1991-03-31 04:00:00
    #6  1991-03-31 05:00:00 1991-03-31 05:00:00
    #7           1991-04-01 1991-04-01 00:00:00
    #8           1991-04-01 1991-04-01 01:00:00
    #9           1991-04-01 1991-04-01 02:00:00
    #10          1991-04-01 1991-04-01 03:00:00
    #11          1991-04-01 1991-04-01 04:00:00
    #12          1991-04-01 1991-04-01 05:00:00
    

    您可以在Date_time1 列上运行as.POSIXct 以将其转换为POSIXct 对象。

    数据

    df <- structure(list(Date_time = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 
    7L, 7L, 7L, 7L, 7L, 7L), .Label = c("1991-03-31 00:00:00", "1991-03-31 01:00:00", 
    "1991-03-31 02:00:00", "1991-03-31 03:00:00", "1991-03-31 04:00:00", 
    "1991-03-31 05:00:00", "1991-04-01"), class = "factor")), class = 
    "data.frame", row.names = c(NA, -12L))
    

    【讨论】:

    • 我非常喜欢这个解决方案,但由于某种原因,当我尝试应用到我的数据时,第一次填写的时间仍然从 16:00:00 开始,而不是 00:00:00。但是,您的示例数据效果很好。
    • @dough 你能像我使用dput 那样用前几行数据更新你的帖子吗?执行dput(head(df, 25)) 并将输出复制/粘贴到您的帖子中。
    • 由于您所在的时区,它可能会导致 16:00 而不是 00:00。在对 as.POSIXct 的调用中使用 tz = 参数。也可以查看它的帮助页面
    • @RonakShah 我从我的真实数据中添加了前几行。
    • @PavoDive no 包括时区没有帮助。我用 Date_time=as.POSIXct((Date_time), origin="1970-01-01", tz="America/Los_Angeles", format="%Y-%m-%d %H:%M:%S" )。但是,我确实想避免将数据转换为日期时间格式,因为它似乎使事情复杂化
    【解决方案3】:

    我没有将丢失的时间添加到完整的时间序列数据集中,而是最终不得不返回到仅包含一个月数据的单个数据集。缺少数据的月份总是四月,因此是 30 天。然后以下工作:

    #Fix April Datasets missing hour data
    hours=c("00:00:00", "01:00:00", "02:00:00", "03:00:00", "04:00:00", "05:00:00", "06:00:00", "07:00:00", "08:00:00", "09:00:00", "10:00:00", "11:00:00", "12:00:00","13:00:00", "14:00:00", "15:00:00", "16:00:00", "17:00:00", "18:00:00", "19:00:00", "20:00:00","21:00:00", "22:00:00", "23:00:00")
    pattern=glob2rx("******04**.csv")
    
    #Monthly Dataset
    MonthlyData_filenames=list.files(path="~/.../Hourly",
                            pattern=pattern, full.names = T)
    for(i in 1:length(MonthlyData_filenames)){
      input = read.csv(MonthlyData_filenames[i], head=TRUE, sep=",")
      if(nchar(as.character(input$Date_time))>=19){
        next
      }
      output = input %>%
        mutate(hour = rep(hours, times=30)) %>%
        mutate(Date_time = paste(Date_time, hour, sep=" ")) %>%
        select(-hour)
      write.csv(output, MonthlyData_filenames[i], row.names=FALSE)
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-15
      • 2011-04-03
      • 1970-01-01
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2021-11-15
      • 1970-01-01
      相关资源
      最近更新 更多