【问题标题】:Conditionally add row with variable in same column of other variable有条件地在其他变量的同一列中添加带有变量的行
【发布时间】:2021-06-08 12:46:37
【问题描述】:

我有类似 df1(以毫秒为单位的时间)之类的东西,但随后有数千行:

df1 <- data.frame(time=c(105, 202, 305, 408, 505, 608), event=c("", "", "", "onset", "", ""))

我想要做的是,对于“onset”的每个实例,在同一列中添加变量“start”,并在该实例之前 200ms 添加。所以,在这个简化的情况下,它应该是这样结束的:

df2 <- data.frame(time=c(105, 202, 208, 305, 408, 505, 608), event=c("", "", "start", "", "onset", "", ""))

我一直无法弄清楚如何做到这一点,非常感谢帮助!

【问题讨论】:

    标签: r dplyr data-science data-wrangling


    【解决方案1】:

    我们可以使用data.table 方法

    library(data.table)
    rbind(setDT(df1),
            df1[event == 'onset'][, c('time', 'event')
            := .(time - 200, 'start')])[order(time)]
    

    -输出

     time event
    1:  105      
    2:  202      
    3:  208 start
    4:  305      
    5:  408 onset
    6:  505      
    7:  608      
    

    【讨论】:

    • 使用data.table 很酷。 (+1)
    【解决方案2】:

    我不确定你在寻找什么样的解决方案,所以这里是 R-base 代码:

    df3 <- df1[ df1$event == "onset", ]
    df3$time <- df3$time - 200
    df3$event <- "start"
    df4 <- rbind( df1, df3 )
    df4 <- df4[ order(df4$time), ]
    df4
    
    #   time event
    #1   105      
    #2   202      
    #41  208 start
    #3   305      
    #4   408 onset
    #5   505      
    #6   608 
    

    【讨论】:

      【解决方案3】:

      您还可以对数据中任意数量的onset 值使用以下解决方案:

      library(dplyr)
      library(purrr)
      
      df %>%
        mutate(is_onset = ifelse(event == "onset", 1, 0),
               is_onset = ifelse(is_onset == 1, cumsum(is_onset), 0)) %>%
        group_split(is_onset) %>%
        map_dfr(~ if(.x$is_onset[1]) {
          .x %>% 
            add_row(event = "start", time = .x$time - 200, .before = 1)
        } else {
          .x
        }) %>%
        select(-is_onset) %>%
        arrange(time)
      
      
      # A tibble: 7 x 2
         time event  
        <dbl> <chr>  
      1   105 ""     
      2   202 ""     
      3   208 "start"
      4   305 ""     
      5   408 "onset"
      6   505 ""     
      7   608 "" 
      

      【讨论】:

        【解决方案4】:

        filter 对于'onset' 事件,更改timeevent 的值并将数据绑定到原始数​​据框。

        library(dplyr)
        
        df1 %>%
          filter(event == 'onset') %>%
          mutate(time = time - 200, 
                 event = 'start') %>%
          bind_rows(df1) %>%
          arrange(time)
        
        #  time event
        #1  105      
        #2  202      
        #3  208 start
        #4  305      
        #5  408 onset
        #6  505      
        #7  608      
        

        在基础 R 中 -

        df2 <- rbind(df1, transform(subset(df1, event == 'onset'),
                          time = time - 200,  event = 'start'))
        
        df2[order(df2$time), ]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-06-17
          • 1970-01-01
          • 1970-01-01
          • 2020-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-12
          相关资源
          最近更新 更多