【问题标题】:Identify rows before and after an event识别事件前后的行
【发布时间】:2020-04-26 00:26:12
【问题描述】:

我想为事件前三天(从 -3 到 -1)、事件当天 (0) 和事件后三天(1 到 3)分配数字。

示例数据:

da1 <- data.frame(day = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22), event = c(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0))

da1
   day event
1    1     0
2    2     0
3    3     0
4    4     0
5    5     0
6    6     0
7    7     0
8    8     1
9    9     0
10  10     0
11  11     0
12  12     0
13  13     0
14  14     0
15  15     0
16  16     0
17  17     1
18  18     0
19  19     0
20  20     0
21  21     0
22  22     0

我想创建新的变量标识符,使其看起来像这样:

da2 <- data.frame(day = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22), event = c(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0), identifier= c(0,0,0,0,-3,-2,-1,0,1,2,3,0,0,-3,-2,-1,0,1,2,3,0,0))

da2
   day event identifier
1    1     0          0
2    2     0          0
3    3     0          0
4    4     0          0
5    5     0         -3
6    6     0         -2
7    7     0         -1
8    8     1          0
9    9     0          1
10  10     0          2
11  11     0          3
12  12     0          0
13  13     0          0
14  14     0         -3
15  15     0         -2
16  16     0         -1
17  17     1          0
18  18     0          1
19  19     0          2
20  20     0          3
21  21     0          0
22  22     0          0

【问题讨论】:

    标签: r function dplyr transform tidyverse


    【解决方案1】:

    这是一个基本的 R 解决方案

    r <- rep(0,nrow(da1))
    da2 <- within(da1,identifier <- replace(r,sapply(which(event==1), `+`, -3:3),-3:3))
    
    # or the line below
    # da2 <- within(da1,identifier <- rowSums(sapply(which(event==1),function(x) replace(r,x + (-3:3), -3:3))))
    
    

    这样

    > da2
       day event identifier
    1    1     0          0
    2    2     0          0
    3    3     0          0
    4    4     0          0
    5    5     0         -3
    6    6     0         -2
    7    7     0         -1
    8    8     1          0
    9    9     0          1
    10  10     0          2
    11  11     0          3
    12  12     0          0
    13  13     0          0
    14  14     0         -3
    15  15     0         -2
    16  16     0         -1
    17  17     1          0
    18  18     0          1
    19  19     0          2
    20  20     0          3
    21  21     0          0
    22  22     0          0
    

    【讨论】:

      【解决方案2】:

      这是基础 R 中的一种方式:

      da1$identifier <- 0
      inds <- which(da1$event == 1)
      da1$identifier[c(sapply(inds, `+`, -3:3))] <- -3:3
      
      da1
      #   day event identifier
      #1    1     0          0
      #2    2     0          0
      #3    3     0          0
      #4    4     0          0
      #5    5     0         -3
      #6    6     0         -2
      #7    7     0         -1
      #8    8     1          0
      #9    9     0          1
      #10  10     0          2
      #11  11     0          3
      #12  12     0          0
      #13  13     0          0
      #14  14     0         -3
      #15  15     0         -2
      #16  16     0         -1
      #17  17     1          0
      #18  18     0          1
      #19  19     0          2
      #20  20     0          3
      #21  21     0          0
      #22  22     0          0
      

      【讨论】:

        【解决方案3】:

        我认为这适用于 tidyverse。但是,如果有 7 天的重叠期,则不会:

        library('tidyverse')
        events = da1 %>% 
          filter(event == 1)
        
        expand_event = function(day){
          tibble(identifier = -3:3,
                 day = day + identifier)
        }
        
        da1 = events[['day']] %>% 
          lapply(expand_event) %>% 
          bind_rows() %>% 
          right_join(da1) %>% 
          mutate(identifier = replace_na(identifier, 0))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多