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
注意使用if
,if(df.data$Time >= df.trial.params$Trial.Start)
会检查总列是否更高。
要遍历每一行,您需要矢量化版本 ifelse()
假设我有两个数据框:
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
注意使用if
,if(df.data$Time >= df.trial.params$Trial.Start)
会检查总列是否更高。
要遍历每一行,您需要矢量化版本 ifelse()