【问题标题】:Expand periods to regularly occuring timestamps将周期扩展到定期出现的时间戳
【发布时间】:2018-07-27 05:26:50
【问题描述】:

必须修改原始帖子以包含更好的示例

我有一个基于时间的数据的小标题,其中包含开始时间、结束时间和以下一般形式的类变量:

制作表格的代码:

library(lubridate)
st <- c(ymd_hms("2016-01-01 00:35:00"),
        ymd_hms("2016-01-01 00:39:00"),
        ymd_hms("2016-01-01 00:54:00"),
        ymd_hms("2016-01-01 00:56:00"),
        ymd_hms("2016-01-01 00:57:00"))

en <- c(ymd_hms("2016-01-01 00:36:00"),
        ymd_hms("2016-01-01 00:45:00"),
        ymd_hms("2016-01-01 00:55:00"),
        ymd_hms("2016-01-01 00:57:00"),
        ymd_hms("2016-01-01 00:58:00"))

cl <- c("a","a","a","b","b")

df <- tibble(st,en,cl)

周期不一致,数据中存在隐藏类:本质上,数据中未明确列出的时间在本例中属于第三类。

我需要一种方法来将此表扩展为具有固定周期(1 分钟),以便我可以将缺失的类分配给这些周期;目标是:

我确信这可以使用 dplyr 和 lubridate 来完成,但一直无法完成。请记住,我的数据集非常庞大,因此最好采用非循环方法。

提前致谢,

先生

【问题讨论】:

    标签: r dplyr timestamp lubridate


    【解决方案1】:

    试试这个:

    df_exp <- tibble(st = seq.POSIXt(from = min(st), to = max(st), by = "min"),
                     en = st + 60)
    merge(df_exp, df, all = T)
    

    首先,创建所有开始时间。结束时间只是开始时间加上 1 分钟。与包含类信息的数据框合并。顺便说一句:您的开始时间和结束时间确实重叠,这可能是某些任务的问题...

    编辑以符合您更新后的要求:

    library(tidyr)
    library(dplyr)
    df_exp <- tibble(st = seq.POSIXt(from = min(st), to = max(en), by = "min"), en = st + 60)
    
    # with tidyr 0.8
    df_n <- df %>% 
      rowwise() %>% 
      mutate(st = list(as.character(seq.POSIXt(from = st, to = en, by = "min"))[-length(seq.POSIXt(from = st, to = en, by = "min"))])) %>% 
      unnest() %>% 
      select(-en) %>% 
      mutate(st = as.POSIXct(st))
    
    df_exp %>% left_join(df_n)
    
    # with tidyr 0.8.1 (untested)
    df_n <- df %>% 
      rowwise() %>% 
      mutate(st = list(seq.POSIXt(from = st, to = en, by = "min")[-length(seq.POSIXt(from = st, to = en, by = "min"))])) %>% 
      unnest() %>% 
      select(-en)
    
    df_exp %>% left_join(df_n)
    

    【讨论】:

    • 谢谢蒂诺。这几乎正​​是我所做的,但是我与 dplyr 的 left_join 进行了合并...我的问题,多亏了你,现在很清楚了,我只是在开始时间而不是开始时间和结束时间合并。干杯!!!
    • 很高兴它对你有用。尽管我通常也使用大部分 tidyverse,但我尝试坚持使用 SO 上的 base 函数只是为了重现性 - 在此示例中无需为简单任务添加另一个包。跨度>
    • 其实蒂诺,我收回了。该解决方案仅在这种情况下有效,因为分配了类的间隔只有 1 分钟宽。当分类间隔大于 1min 时,求解失败。我原来的例子不够笼统......
    • 再次感谢。我实际上设法用不同的方法获得了预期的结果,但这有点“循环”。我认为您的方式很可能会在大型数据集上表现得更好。无论如何,我都会在主帖上发布我的解决方案。无论如何,非常感谢您的快速回复。先生
    【解决方案2】:

    好的,我设法找到了解决方案,但它有点“循环”方面。我认为蒂诺的回答更好。对于什么是值得的,这是我的答案:

    ##################################################
    #Regular period DF covering the entire period in the initial data
    df_regular <- tibble(st = seq(min(df$st),max(df$en)-59,60),
                         en = st + 59)
    ##################################################
    #Creates variable with number of 1-min periods per row in initial data
    df$periods <- as.integer((df$en-df$st + 1)/60)
    
    ##################################################
    #Scan each row
    listDates <- list()
    listClass <- list()
    
    k <- 1
    for (i in 1:nrow(df)) {
      for(j in 1:df$periods[i]) {
        listDates[k] <- c(df$st[i]+(j-1)*60)
        listClass[k] <- c(df$cl[i])
    
        k <- k+1
      }
    }
    
    #################################################
    #create output table
    df_out <- tibble(st = unlist(listDates) %>% as_datetime(),
                     cl = unlist(listClass)) %>%
      right_join(df_regular[1],by=c("st" ="st")) %>%
      mutate(en = st + 59) %>%
      select(st,en,cl)
    #################################################
    

    还纳入了 Tino 关于避免日期重叠的建议。

    干杯,

    先生

    【讨论】:

      猜你喜欢
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 2013-12-08
      相关资源
      最近更新 更多