【问题标题】:creating a variable including the lag and lead of a date-time variable创建一个变量,包括日期时间变量的滞后和超前
【发布时间】:2020-12-01 19:24:21
【问题描述】:

我有一个类似于以下示例的数据集。我正在尝试创建一个与“预期”变量相同的变量。即如果 date_time 为“2020-01-02 12:00”,则创建一个包含 date_time 的 lag、lead 和 level 值的变量。

提前谢谢你。

    df <- tibble(
             date_time = c("2020-01-01 10:00","2020-01-01 11:00","2020-01-01 12:00","2020-01-01 13:00","2020-01-01 14:00","2020-01-02 10:00","2020-01-02 11:00","2020-01-02 12:00","2020-01-03 10:00","2020-01-03 11:00"), 
             
             date = c("2020-01-01","2020-01-01","2020-01-01","2020-01-01","2020-01-01","2020-01-02","2020-01-02","2020-01-02","2020-01-03","2020-01-03"),
               x= seq.default(1,5.5,.5),
date_time_NA = c(NA,"2020-01-01 11:00",NA,NA,NA,NA,NA,"2020-01-02 12:00",NA,NA),
            expected = c("2020-01-01 10:00","2020-01-01 11:00","2020-01-01 12:00",NA,NA,NA,"2020-01-02 11:00","2020-01-02 12:00","2020-01-03 10:00",NA) 
             )
df

新示例

我改变了上面的例子。所以我试图告诉 R 找到 date_time_NA 没有丢失的位置,然后创建一个变量,包括 date_time 的滞后、领先和水平值(类似于预期)。

更新:另一种解决方案

我使用@akrun 分享的代码提出了一个解决方案。这可能不是一个非常聪明的解决方案;但是,我发现它很直观。 主要思想是使用 ifelse 查找 date_time_NA 没有丢失的位置。然后我们可以再次使用 row_number() 并加 1 以便它可以找到领先并减 1 以便它可以找到滞后位置并将它们替换为 date_time 的值。

df %>%
 mutate(na_row = ifelse(!is.na(date_time_NA),row_number(),NA),
       
         row_level_lag = ifelse(row_number() %in% c(na_row), date_time,NA), 
       
         row_level_now = ifelse(row_number() %in% c(na_row + 1), date_time,NA),
       
         row_level_lead = ifelse(row_number() %in% c(na_row - 1), date_time,NA),
       
         date_time_expected = glue("{row_level_lag} {row_level_now} {row_level_lead}"), 
       
         date_time_expected = stringr::str_replace_all(string = date_time_expected,pattern = "NA",replacement = "")) 

【问题讨论】:

    标签: r datetime


    【解决方案1】:

    我们可以使用match 获取相关'date_time' 值的索引,然后通过添加来自-1:1 的序列来获取上一个值和下一个值的索引。使用它来创建一个具有“date_time”子集值的“新”列

    i1 <- match("2020-01-02 12:00", df$date_time)
    i2 <- i1 + (-1:1)
    df$new <- NA_character_
    df$new[i2] <- df$date_time[i2]
    

    -输出

    df
    # A tibble: 10 x 5
    #   date_time        date           x expected         new             
    #   <chr>            <chr>      <dbl> <chr>            <chr>           
    # 1 2020-01-01 10:00 2020-01-01   1   <NA>             <NA>            
    # 2 2020-01-01 11:00 2020-01-01   1.5 <NA>             <NA>            
    # 3 2020-01-01 12:00 2020-01-01   2   <NA>             <NA>            
    # 4 2020-01-01 13:00 2020-01-01   2.5 <NA>             <NA>            
    # 5 2020-01-01 14:00 2020-01-01   3   <NA>             <NA>            
    # 6 2020-01-02 10:00 2020-01-02   3.5 <NA>             <NA>            
    # 7 2020-01-02 11:00 2020-01-02   4   2020-01-02 11:00 2020-01-02 11:00
    # 8 2020-01-02 12:00 2020-01-02   4.5 2020-01-02 12:00 2020-01-02 12:00
    # 9 2020-01-03 10:00 2020-01-03   5   2020-01-03 10:00 2020-01-03 10:00
    #10 2020-01-03 11:00 2020-01-03   5.5 <NA>             <NA>            
    

    使用dplyr,我们可以使用replace 来替换'date_time' 中不是'date_time' 的matched 索引的值以及NA 的上一个和下一个索引索引

    library(dplyr)
    df %>% 
       mutate(new = replace(date_time,
       !row_number()  %in% (match("2020-01-02 12:00", 
               df$date_time) + (-1:1)), NA_character_ ))
    

    -输出

    # A tibble: 10 x 5
    #   date_time        date           x expected         new             
    #   <chr>            <chr>      <dbl> <chr>            <chr>           
    # 1 2020-01-01 10:00 2020-01-01   1   <NA>             <NA>            
    # 2 2020-01-01 11:00 2020-01-01   1.5 <NA>             <NA>            
    # 3 2020-01-01 12:00 2020-01-01   2   <NA>             <NA>            
    # 4 2020-01-01 13:00 2020-01-01   2.5 <NA>             <NA>            
    # 5 2020-01-01 14:00 2020-01-01   3   <NA>             <NA>            
    # 6 2020-01-02 10:00 2020-01-02   3.5 <NA>             <NA>            
    # 7 2020-01-02 11:00 2020-01-02   4   2020-01-02 11:00 2020-01-02 11:00
    # 8 2020-01-02 12:00 2020-01-02   4.5 2020-01-02 12:00 2020-01-02 12:00
    # 9 2020-01-03 10:00 2020-01-03   5   2020-01-03 10:00 2020-01-03 10:00
    #10 2020-01-03 11:00 2020-01-03   5.5 <NA>             <NA>            
    

    更新

    如果match有多个元素,那么我们创建一个分组列并应用相同的代码

    library(tidyr)
    df %>%
        mutate(grp = lead(cumsum(!is.na(date_time_NA)))) %>%
        fill(grp) %>%
        group_by(grp) %>% 
        mutate(new = replace(date_time,
          !row_number()  %in% (match(date_time_NA[complete.cases(date_time_NA)][1],
                date_time) + (-1:1)), NA_character_ )) %>%
         ungroup %>%
        select(-grp)
    # A tibble: 10 x 6
    #   date_time        date           x date_time_NA     expected         new             
    #   <chr>            <chr>      <dbl> <chr>            <chr>            <chr>           
    # 1 2020-01-01 10:00 2020-01-01   1   <NA>             2020-01-01 10:00 2020-01-01 10:00
    # 2 2020-01-01 11:00 2020-01-01   1.5 2020-01-01 11:00 2020-01-01 11:00 2020-01-01 11:00
    # 3 2020-01-01 12:00 2020-01-01   2   <NA>             2020-01-01 12:00 2020-01-01 12:00
    # 4 2020-01-01 13:00 2020-01-01   2.5 <NA>             <NA>             <NA>            
    # 5 2020-01-01 14:00 2020-01-01   3   <NA>             <NA>             <NA>            
    # 6 2020-01-02 10:00 2020-01-02   3.5 <NA>             <NA>             <NA>            
    # 7 2020-01-02 11:00 2020-01-02   4   <NA>             2020-01-02 11:00 2020-01-02 11:00
    # 8 2020-01-02 12:00 2020-01-02   4.5 2020-01-02 12:00 2020-01-02 12:00 2020-01-02 12:00
    # 9 2020-01-03 10:00 2020-01-03   5   <NA>             2020-01-03 10:00 2020-01-03 10:00
    #10 2020-01-03 11:00 2020-01-03   5.5 <NA>             <NA>             <NA>            
    

    【讨论】:

    • 谢谢@akrun,有什么方法可以在这里使用 dplyr 来解决问题,或者以某种方式使用您的代码和管道。
    • 您的解决方案完美运行。我想知道您是否愿意在这里帮助我:我的数据集相对较大,从技术上讲,我无法提及我将围绕其创建新变量的日期时间值。相反,我创建了一个包含 NA 值的新变量,但我感兴趣的日期时间对象除外。假设我创建了一个名为 date_time_NA 的新变量,因此它对于除我感兴趣的值之外的所有值都是 NA。我尝试使用 which(!is.na(date_time_NA),但是它不起作用。
    • @SeyedHosseini 如果您包含NA 元素。您可以使用is.na 创建一个索引,您能否更新一个小示例以便我对其进行测试。谢谢
    • 我刚刚改了例子。
    • @akrun,我们可以在这里使用 match 如果例如我想在日期匹配的情况下获取同一行中的值,或者我得到前一个?我有这个问题,我试图找出一种方法来比较两个时间列并在第二列中扩展以获得更长的 0/1 序列。谢谢! stackoverflow.com/questions/65098710/…
    猜你喜欢
    • 2013-08-31
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多