嵌套 ifelse 在 R 中输出 3 个响应

Nested ifelse to output 3 responses in R

这是我原来 post 中的一个相关问题,在此处找到:

我有 2 个来自实验的数据框。第一个 df 在 40 分钟内读取(大致)连续信号。有 5 列,1:3 是二进制的 - 表示是否按下了按钮。第 4 列是第 2 列或第 3 列是否被推送的二进制。第 5 列是以秒为单位的近似时间。下面的 df 示例:

initiate left right l or r time
0 0 1 1 2.8225
0 0 1 1 2.82375
0 0 1 1 2.82500
0 0 1 1 2.82625
1 0 0 0 16.8200
1 0 0 0 16.8212

等等

第二个数据框是会话信息,其中每一行都是一次试验,通常有 100-150 行,具体取决于一天。我有一列标记试用开始时间,另一列标记试用结束时间(以秒为单位)。我还有另一列说明试验是否有干预。下面 df 的示例(我省略了几个不相关的列):

trial control t start t end
1 0 16.64709 35.49431
2 0 41.81843 57.74304
3 0 65.54510 71.16612
4 0 82.65743 87.30914
11 3 187.0787 193.5898
12 0 200.0486 203.1883
30 3 415.1710 418.0405

等等

对于第一个数据框,我想创建一个列来指示按钮是否在试验中被按下。如果确实在试验中按下了按钮,我需要根据干预对其进行标记。 这是基于 2nd df 中的开始和结束时间以及控制信息。在此 table 中,0 = 干预,3 = 控制。

我希望它看起来像这样(iti = inter-trial,wt_int = within trial & intervention,wt_control = within trial & control):

initiate left right l or r time trial_type
0 0 1 1 2.8225 iti
0 0 1 1 2.82375 iti
0 0 1 1 2.82500 iti
0 0 1 1 2.82625 iti
1 0 0 0 16.82000 wt_int
1 0 0 0 16.82125 wt_int
1 0 0 0 187.0800 wt_control

等等

根据之前的建议,我尝试了嵌套的 ifelse 语句但没有成功。我可以用不同的失败尝试将所有试验标记为“iti”或“wt_int”,或者在第 1037 行出现错误(当它从 iti 变为 wt 时)。从我最初的问题开始,我现在在我的第一个 df 中有一个“试用”列,我将其用于以下代码。也许有更直接的方法结合原始代码?

中途出错:

df %>% 
  rowwise() %>% 
  mutate(trial_type = ifelse(any(trial == "wt" & df2$control == 0,
                                 ifelse(trial == "wt" & df2$control == 3,
                                        "wt_omission", "iti"), "wt_odor")))

也试过这个,将所有标记为 wt_int:

df$trial_type <- ifelse(df$trial == 'wt' && df2$control == 0,
                        ifelse(df$trial == 'wt' && df2$control == 3, 
                               "wt_control", "iti"), "wt_int")

谢谢!

您可以使用 cut 创建间隔并检查是否有值落入其中:

library(dplyr)

df1 %>% 
  mutate(
    check_1 = cut(time, breaks = df2$t_start, labels = FALSE),
    check_2 = coalesce(cut(time, breaks = df2$t_end, labels = FALSE), 0),
    check_3 = df2$control[check_1],
    trial_type = case_when(
      check_1 - check_2 == 1 & check_3 == 0 ~ "wt_int",
      check_1 - check_2 == 1 & check_3 == 3 ~ "wt_control",
      TRUE ~ "iti"
      )
    ) %>% 
  select(-starts_with("check_"))

这个returns

# A tibble: 7 x 6
  initiate  left right l_or_r   time trial_type
     <dbl> <dbl> <dbl>  <dbl>  <dbl> <chr>     
1        0     0     1      1   2.82 iti       
2        0     0     1      1   2.82 iti       
3        0     0     1      1   2.82 iti       
4        0     0     1      1   2.83 iti       
5        1     0     0      0  16.8  wt_int    
6        1     0     0      0  16.8  wt_int    
7        1     0     0      0 187.   wt_control

数据

df1 <- structure(list(initiate = c(0, 0, 0, 0, 1, 1, 1), left = c(0, 
0, 0, 0, 0, 0, 0), right = c(1, 1, 1, 1, 0, 0, 0), l_or_r = c(1, 
1, 1, 1, 0, 0, 0), time = c(2.8225, 2.82375, 2.825, 2.82625, 
16.82, 16.8212, 187.08)), class = c("spec_tbl_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -7L), spec = structure(list(
    cols = list(initiate = structure(list(), class = c("collector_double", 
    "collector")), left = structure(list(), class = c("collector_double", 
    "collector")), right = structure(list(), class = c("collector_double", 
    "collector")), l_or_r = structure(list(), class = c("collector_double", 
    "collector")), time = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1L), class = "col_spec"))

df2 <- structure(list(trial = c(1, 2, 3, 4, 11, 12, 30), control = c(0, 
0, 0, 0, 3, 0, 3), t_start = c(16.64709, 41.81843, 65.5451, 82.65743, 
187.0787, 200.0486, 415.171), t_end = c(35.49431, 57.74304, 71.16612, 
87.30914, 193.5898, 203.1883, 418.0405)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -7L), spec = structure(list(
    cols = list(trial = structure(list(), class = c("collector_double", 
    "collector")), control = structure(list(), class = c("collector_double", 
    "collector")), t_start = structure(list(), class = c("collector_double", 
    "collector")), t_end = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1L), class = "col_spec"))