根据R中的时间戳插入新的系列行

时间:2016-10-24 13:40:34

标签: r timestamp row

我有一个带有两个参数(日期和雕像)的data.table,现在我想根据原始表格插入一整天的新行。

数据规则:

  1. “状态”列仅包含" 0"和" 1"
  2. 表中未记录的时间戳与表中下一个最接近的tiemstamp相同。
  3. 日期列始终按时间增加:)
  4. 例如,一个简单的输入:

    enter image description here

    使用以下代码创建数据:

    import sublime, sublime_plugin
    import sort
    
    def line_length_sort(txt):
        txt.sort(lambda a, b: cmp(len(a), len(b)))
        return txt
    
    class SortLinesLengthCommand(sublime_plugin.TextCommand):
        def run(self, edit, reverse=False, remove_duplicates=False):
            view = self.view
    
            sort.permute_lines(line_length_sort, view, edit)
    
            if reverse:
                sort.permute_lines(sort.reverse_list, view, edit)
    
            if remove_duplicates:
                sort.permute_lines(sort.uniquealise_list, view, edit)
    

    输出是:

    enter image description here

    我的解决方案:

    1. 计算每两行的时差,然后保存在名为time_diff
    2. 的新列中
    3. 根据time_diff
    4. 在循环中插入新行

      它可以工作,但问题是计算时间太长,因为这么多循环。我认为这个案例可以有一个更简单的解决方案

      非常感谢任何帮助或建议:)

      谢谢!

2 个答案:

答案 0 :(得分:3)

这是另一个想法

library(dplyr)
library(tidyr)
library(lubridate)

dd %>%
  mutate(date = ymd_hms(date)) %>%
  complete(date = seq(floor_date(min(date), "day"), max(date), 1)) %>%
  fill(status, .direction = "up")

给出了:

## A tibble: 9 × 2
#                 date status
#               <dttm>  <dbl>
#1 2015-07-01 00:00:00      0
#2 2015-07-01 00:00:01      0
#3 2015-07-01 00:00:02      0
#4 2015-07-01 00:00:03      1
#5 2015-07-01 00:00:04      1
#6 2015-07-01 00:00:05      0
#7 2015-07-01 00:00:06      0
#8 2015-07-01 00:00:07      0
#9 2015-07-01 00:00:08      0

答案 1 :(得分:1)

更快地执行此操作的一种方法是使用zoomerge两个时间序列(as shown in the SO answer):

  1. 第一个是根据您的数据构建的。
  2. 第二个是一个时间序列,其中包含随时开始和结束的观察结果。
  3. 然后使用NA填写合并中的na.locf。在代码中:

    ## first convert your date column to date-time
    dd$date <- as.POSIXct(dd$date,format="%Y-%m-%d %H:%M:%S")
    ## set dd as data frame
    setDF(dd)
    library(zoo)
    ## construct zoo time series for your data
    dd.zoo <- zoo(dd[,-1],dd[,1])
    ## do the merge and use `na.locf` to fill in the NA's
    output <- na.locf(merge(dd.zoo,
                            zoo(,seq(as.POSIXct("2015-07-01 00:00:00",format="%Y-%m-%d %H:%M:%S"),
                                     end(dd.zoo),by="sec")), all=TRUE),
                      fromLast=TRUE)
    

    此处,要合并的时间序列的开头和结尾是2015-07-01 00:00:00到数据末尾的秒数。通常,您可以指定任意两个时间点。 merge使用all=TRUE执行外部联接,其中所有观察值都在输出中连接。那些不在原始数据中的人将填入NA。最后,将na.locffromLast=TRUE一起使用,将NA替换为最近一次观察后最近的非NA

    将您的数据dd转换为数据框:

    print(output)
    ##2015-07-01 00:00:00 2015-07-01 00:00:01 2015-07-01 00:00:02 2015-07-01 00:00:03 
    ##                  0                   0                   0                   1 
    ##2015-07-01 00:00:04 2015-07-01 00:00:05 2015-07-01 00:00:06 2015-07-01 00:00:07 
    ##                  1                   0                   0                   0 
    ##2015-07-01 00:00:08 
    ##                  0 
    

    请注意,outputzoo系列。要转换回data.table

    output <- data.table(date=index(output),status=as.data.frame(output)$output)
    ##                  date status
    ##1: 2015-07-01 00:00:00      0
    ##2: 2015-07-01 00:00:01      0
    ##3: 2015-07-01 00:00:02      0
    ##4: 2015-07-01 00:00:03      1
    ##5: 2015-07-01 00:00:04      1
    ##6: 2015-07-01 00:00:05      0
    ##7: 2015-07-01 00:00:06      0
    ##8: 2015-07-01 00:00:07      0
    ##9: 2015-07-01 00:00:08      0