R. 根据不同数据框中的值设置数据框中的值

R. Setting value in data frame based on values in different data frame

假设我有两个数据框:

df.trial.params =

Session     Trial.Start    Trial.End    Trial.Num
1           30             50           1
1           51             80           2
2           30             50           1
2           51             80           2
3           30             50           1
3           51             80           2

df.data=

Session    Time
1          31
1          33
1          52
1          72
2          31
2          33
2          52
2          72
3          31
3          33
3          52
3          72

我想添加一列 (df.data$trial.num),它基于 df.trial.params 中的参数。此匹配分两步完成: 第 1 步:匹配会话

if(df.data$Session == df.trial.params$Session)

第 2 步:匹配时间,使其位于试用开始和结束时间之内

if((df.data$Time >= df.trial.params$Trial.Start) & (df.data$Time <= df.trial.params$Trial.End))

最终结果是这样的:

Session    Time    Trial.Num
1          31      1
1          33      1
1          52      2
1          72      2
2          31      1
2          33      1
2          52      2
2          72      2
3          31      1
3          33      1
3          52      2
3          72      2

我真的有点不知所措,因为我使用 R 的经验非常有限。我看过一些使用 with() 的帖子,但我不确定如何使用多个数据帧。 感谢您提供的所有帮助,如果此问题已在其他地方得到解答(我找不到),我深表歉意

已编辑以显示所需的最终产品。

可以按Session合并数据框,然后按时间过滤:

library(dplyr)
merge(df.trial.params, df.data, by = 'Session') %>% 
      filter(Time >= Trial.Start, Time <= Trial.End) %>% 
      select(Session, Time, Trial.Num)

#    Session Time Trial.Num
# 1        1   31         1
# 2        1   33         1
# 3        1   52         2
# 4        1   72         2
# 5        2   31         1
# 6        2   33         1
# 7        2   52         2
# 8        2   72         2
# 9        3   31         1
# 10       3   33         1
# 11       3   52         2
# 12       3   72         2

我们可以用 data.table

library(data.table)
setDT(df.data)[df.trial.params, on = "Session", allow.cartesian=TRUE
     ][Time >=Trial.Start & Time <= Trial.End][,  (3:4) := NULL][]
#     Session Time Trial.Num
# 1:       1   31         1
# 2:       1   33         1
# 3:       1   52         2
# 4:       1   72         2
# 5:       2   31         1
# 6:       2   33         1
# 7:       2   52         2
# 8:       2   72         2
# 9:       3   31         1
#10:       3   33         1
#11:       3   52         2
#12:       3   72         2

或使用foverlaps

df.data1 <- transform(df.data, Trial.Start = Time, Trial.End = Time)[-2]
setDT(df.trial.params, key = c("Session", "Trial.Start", "Trial.End"))
setDT(df.data1, key = c("Session", "Trial.Start", "Trial.End"))
foverlaps(df.data1, df.trial.params, type="within")[,
               Time := i.Trial.Start][, c(1, 7, 4), with = FALSE]
#    Session Time Trial.Num
# 1:       1   31         1
# 2:       1   33         1
# 3:       1   52         2
# 4:       1   72         2
# 5:       2   31         1
# 6:       2   33         1
# 7:       2   52         2
# 8:       2   72         2
# 9:       3   31         1
#10:       3   33         1
#11:       3   52         2
#12:       3   72         2

注意使用ifif(df.data$Time >= df.trial.params$Trial.Start)会检查总列是否更高。 要遍历每一行,您需要矢量化版本 ifelse()