识别 R 中数据框中的第一次出现,然后每三行标记一次

Identify first occurence in dataframe in R and subsequently label every third row

我有一个大型数据帧,我想将其从 120hz 降采样到 40hz。尽管我只能从数据框中取出每三行,但它不够一致。

我有类似下面的数据框:

df <- data.frame(RelativeTime = c(0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550), 
         Marker = c("start_trial", "", "", "", "", "", "", "", "", "", "", "", "start_trial", "", "", "", "", "", "", "", "", "", "", ""), 
         size=c(NA, -1, -1, 4, -1, -1 , 3.5, -1, -1, 4, -1, -1, NA, 4, -1, -1, 2, -1, -1, -1, -1, -1, 4.5, -1),
         trial=c("trial 1", "trial 1", "trial 1", "trial 1", "trial 1", "trial 1", "trial 1", "trial 1", "trial 1", "trial 1", "trial1", "trial1", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2" ))

我想要的是为每个 trial 识别 size 中的第一个非 0 条目。然后 从那里开始 过滤 data.frame 所以只保留每第三行。正如您在此示例中所看到的,每个第一个非 0 数字的起点相对于“trial_onset”是可变的,这给我带来了问题!此外,我需要这种特殊方法(而不是仅仅过滤掉非 0 值)的原因是,有时“大小”值很可能也是 -1 只是由于数据收集点失败。我需要保留那些以供进一步处理。所以,我想得到以下数据框:

df2 <- data.frame(RelativeTime = c(0, 150, 300, 450, 0, 50, 200, 350, 500), 
         Marker = c("start_trial", "", "", "", "start_trial", "", "", "", ""), 
         size=c(NA, 4, 3.5, 4, NA, 4, 2, -1, 4.5),
         trial=c("trial 1", "trial 1", "trial 1", "trial 1", "trial 2", "trial 2", "trial 2", "trial 2", "trial 2"))

非常感谢您的帮助!

你在找这个吗?

library(dplyr) 

df %>%
  group_by(trial) %>%
  filter(cumsum(coalesce(size, -1) > 0) >= 1) %>%
  filter(1:n() %% 3 == 1)

# A tibble: 7 x 4
# Groups:   trial [2]
  RelativeTime Marker  size trial  
         <dbl> <chr>  <dbl> <chr>  
1          150 ""       4   trial 1
2          300 ""       3.5 trial 1
3          450 ""       4   trial 1
4           50 ""       4   trial 2
5          200 ""       2   trial 2
6          350 ""       5   trial 2
7          500 ""       4.5 trial 2

如果您也想保留每个试验的第一行,您可以使用 bind_rows 添加它们。

另一个解决方案:

library(dplyr)
df %>% 
  group_by(trial) %>% 
  mutate(start = cumany(size > 0)) %>% 
  group_by(trial, start) %>% 
  filter(Marker == "start_trial" | seq(start[start == T]) %% 3 == 1)

  RelativeTime Marker         size trial   start
         <dbl> <chr>         <dbl> <chr>   <lgl>
1            0 "start_trial"  NA   trial 1 NA   
2          150 ""              4   trial 1 TRUE 
3          300 ""              3.5 trial 1 TRUE 
4          450 ""              4   trial 1 TRUE 
5            0 "start_trial"  NA   trial 2 NA   
6           50 ""              4   trial 2 TRUE 
7          200 ""              2   trial 2 TRUE 
8          350 ""              5   trial 2 TRUE 
9          500 ""              4.5 trial 2 TRUE