有条件地在其他变量的同一列中添加带有变量的行

Conditionally add row with variable in same column of other variable

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

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

我想做的是,对于每个“开始”实例,在同一列中添加变量“开始”,并在该开始实例之前 200 毫秒添加。所以,在这个简化的例子中它应该像这样结束:

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

我一直无法弄清楚如何做到这一点,将不胜感激!

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), ]

我不确定您正在寻找哪种解决方案,所以这里是 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 

我们可以使用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      

您还可以对数据中任意数量的 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 ""