遍历 R 中的数据帧并测量两个值之间的时间差
Loop through dataframe in R and measure time difference between two values
总结:我正在分析发生的刺激(A&B)和用户可能的反应之间的时间差。
数据集具有以下结构:
structure(list(User = c("005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844"), Date = c("25.11.2015 13:59",
"03.12.2015 09:32", "07.12.2015 08:18", "08.12.2015 19:40", "08.12.2015 19:40",
"22.12.2015 08:52", "22.12.2015 08:50", "22.12.2015 15:42", "22.12.2015 20:46",
"05.01.2016 11:33", "05.01.2016 11:35", "05.01.2016 13:22", "05.01.2016 13:21",
"05.01.2016 13:22", "06.01.2016 09:18", "14.02.2016 22:47", "20.02.2016 21:27",
"01.04.2016 13:52", "24.07.2016 07:03", "04.08.2016 08:25"),
Hour = c(1645L, 1833L, 1928L, 1963L, 1963L, 2288L, 2288L,
2295L, 2300L, 2627L, 2627L, 2629L, 2629L, 2629L, 2649L, 3598L,
3741L, 4717L, 7447L, 7712L), StimuliA = c(1L, 0L, 1L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L,
0L), StimuliB = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 1L,
1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L), Responses = c(0L,
1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L,
1L, 1L, 1L, 0L)), .Names = c("User", "Date", "Hour", "StimuliA",
"StimuliB", "Responses"), row.names = c(NA, -20L), class = c("tbl_df",
"tbl", "data.frame"))
关于数据的附加信息:数据表中的每一行都是一个事件日志,用户在其中感知到某种刺激或执行了一个动作(响应)。时间:项目开始后的"Hour",事件发生的时间。
目标: 总体目标是测量刺激和反应之间的时间。 (如果有的话)我想创建一个循环,遍历每个用户的数据集,如果 Stimuli 的值为 1,它会检查稍后是否有用户的响应,并创建一个包含值的向量A 一个,B 一个。
问题:
我会用 for 循环来执行此操作吗,它遍历每个用户并检查感知到的刺激,如果有值 1,则检查同一用户 ID 在最近的响应中是否具有值 1,然后比较 2 个日期?
子问题 // 我正在努力解决的问题
- 我如何实际遍历每一行并检查它的条件语句,如果为真则执行命令? (如果别的?)。
- 然后我将如何作为命令保存此行中其他单元格的值?
- 然后告诉 R 寻找相同用户 ID(按时间顺序)最接近的 Response 并计算这两个值之间的时间差?
- 最终用这些计算值创建一个向量
想要的结果:
Stimuli A c=(11253, 2122, 56969), Stimuli B c=(19512,107)
到目前为止,我自己编写的代码不是很有用。我正在试验 for 循环和 if 语句,还有 ifelse 函数。
我是 R 的新手,但在 datacamp 上做过多次 类,但我仍在努力将它应用到我自己的硕士论文中。感谢大家的帮助。
附加信息:
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
SQL 语法应该能够为您提供答案,并且是查询此类表格数据的常规方法。 Data.Table
包使这种语法易于访问。
#import necessary library
library(data.table)
#instantiate data table
dt<-data.table(dt)
#convert date field to Date type
dt$Date <- as.POSIXct(dt$Date, format="%d.%m.%Y %H:%M")
#create another date field so as not to lose during join
dt$rollDate<-dt$Date
#create table with stimuliA and set key for sorting/joining purposes
stima.dt <- dt[StimuliA==1,.(User,rollDate,Date,Hour,StimuliA)]
setkey(stima.dt,User,rollDate)
#Same for stimuliB
stimb.dt <- dt[StimuliB==1,.(User,rollDate,Date,Hour,StimuliB)]
setkey(stimb.dt,User,rollDate)
#same for responses table
resp.dt <- dt[Responses==1,.(User,rollDate,Date,Hour,Responses)]
setkey(resp.dt,User,rollDate)
#Join stimuli A table to closes responses
stim.a<-resp.dt[stima.dt,roll=-Inf]
#calculate Hour differences
stim.a[,difftime(Date,i.Date,units="min")]
#Join stimuli B table to closes responses
stim.b<-resp.dt[stimb.dt,roll=-Inf]
#calculate Hour differences
stim.b[,difftime(Date,i.Date,units="min")]
以下是使用 dplyr
的方法。首先,您需要将 Date 列转换为 POSIXct 对象。然后,确保 Date 对象使用 arrange
排序。然后使用 mutate
添加时差列。然后,您可以 filter
对于刺激 A 或 B 为 1 且后跟等于 1 的响应的行。
df$Date <- as.POSIXct(strptime(df$Date,"%d.%m.%Y %H:%M"))
df %>%
arrange(User,Date)%>%
mutate(difftime= difftime(lead(Date),Date, units = "mins") ) %>%
group_by(User)%>%
filter((StimuliA==1 | StimuliB==1) & lead(Responses)==1)
User Date Hour StimuliA StimuliB Responses difftime
<chr> <dttm> <int> <int> <int> <int> <time>
1 005b98f3-5b1b-4d10-bdea-a55d012b2844 2015-11-25 13:59:00 1645 1 0 0 11253 mins
2 005b98f3-5b1b-4d10-bdea-a55d012b2844 2015-12-07 08:18:00 1928 1 0 0 2122 mins
3 005b98f3-5b1b-4d10-bdea-a55d012b2844 2015-12-08 19:40:00 1963 0 1 0 19510 mins
4 005b98f3-5b1b-4d10-bdea-a55d012b2844 2016-01-05 11:35:00 2627 0 1 0 106 mins
5 005b98f3-5b1b-4d10-bdea-a55d012b2844 2016-01-06 09:18:00 2649 1 0 0 56969 mins
总结:我正在分析发生的刺激(A&B)和用户可能的反应之间的时间差。
数据集具有以下结构:
structure(list(User = c("005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844", "005b98f3-5b1b-4d10-bdea-a55d012b2844",
"005b98f3-5b1b-4d10-bdea-a55d012b2844"), Date = c("25.11.2015 13:59",
"03.12.2015 09:32", "07.12.2015 08:18", "08.12.2015 19:40", "08.12.2015 19:40",
"22.12.2015 08:52", "22.12.2015 08:50", "22.12.2015 15:42", "22.12.2015 20:46",
"05.01.2016 11:33", "05.01.2016 11:35", "05.01.2016 13:22", "05.01.2016 13:21",
"05.01.2016 13:22", "06.01.2016 09:18", "14.02.2016 22:47", "20.02.2016 21:27",
"01.04.2016 13:52", "24.07.2016 07:03", "04.08.2016 08:25"),
Hour = c(1645L, 1833L, 1928L, 1963L, 1963L, 2288L, 2288L,
2295L, 2300L, 2627L, 2627L, 2629L, 2629L, 2629L, 2649L, 3598L,
3741L, 4717L, 7447L, 7712L), StimuliA = c(1L, 0L, 1L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L,
0L), StimuliB = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 1L,
1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L), Responses = c(0L,
1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L,
1L, 1L, 1L, 0L)), .Names = c("User", "Date", "Hour", "StimuliA",
"StimuliB", "Responses"), row.names = c(NA, -20L), class = c("tbl_df",
"tbl", "data.frame"))
关于数据的附加信息:数据表中的每一行都是一个事件日志,用户在其中感知到某种刺激或执行了一个动作(响应)。时间:项目开始后的"Hour",事件发生的时间。
目标: 总体目标是测量刺激和反应之间的时间。 (如果有的话)我想创建一个循环,遍历每个用户的数据集,如果 Stimuli 的值为 1,它会检查稍后是否有用户的响应,并创建一个包含值的向量A 一个,B 一个。
问题: 我会用 for 循环来执行此操作吗,它遍历每个用户并检查感知到的刺激,如果有值 1,则检查同一用户 ID 在最近的响应中是否具有值 1,然后比较 2 个日期?
子问题 // 我正在努力解决的问题
- 我如何实际遍历每一行并检查它的条件语句,如果为真则执行命令? (如果别的?)。
- 然后我将如何作为命令保存此行中其他单元格的值?
- 然后告诉 R 寻找相同用户 ID(按时间顺序)最接近的 Response 并计算这两个值之间的时间差?
- 最终用这些计算值创建一个向量
想要的结果:
Stimuli A c=(11253, 2122, 56969), Stimuli B c=(19512,107)
到目前为止,我自己编写的代码不是很有用。我正在试验 for 循环和 if 语句,还有 ifelse 函数。
我是 R 的新手,但在 datacamp 上做过多次 类,但我仍在努力将它应用到我自己的硕士论文中。感谢大家的帮助。
附加信息:
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
SQL 语法应该能够为您提供答案,并且是查询此类表格数据的常规方法。 Data.Table
包使这种语法易于访问。
#import necessary library
library(data.table)
#instantiate data table
dt<-data.table(dt)
#convert date field to Date type
dt$Date <- as.POSIXct(dt$Date, format="%d.%m.%Y %H:%M")
#create another date field so as not to lose during join
dt$rollDate<-dt$Date
#create table with stimuliA and set key for sorting/joining purposes
stima.dt <- dt[StimuliA==1,.(User,rollDate,Date,Hour,StimuliA)]
setkey(stima.dt,User,rollDate)
#Same for stimuliB
stimb.dt <- dt[StimuliB==1,.(User,rollDate,Date,Hour,StimuliB)]
setkey(stimb.dt,User,rollDate)
#same for responses table
resp.dt <- dt[Responses==1,.(User,rollDate,Date,Hour,Responses)]
setkey(resp.dt,User,rollDate)
#Join stimuli A table to closes responses
stim.a<-resp.dt[stima.dt,roll=-Inf]
#calculate Hour differences
stim.a[,difftime(Date,i.Date,units="min")]
#Join stimuli B table to closes responses
stim.b<-resp.dt[stimb.dt,roll=-Inf]
#calculate Hour differences
stim.b[,difftime(Date,i.Date,units="min")]
以下是使用 dplyr
的方法。首先,您需要将 Date 列转换为 POSIXct 对象。然后,确保 Date 对象使用 arrange
排序。然后使用 mutate
添加时差列。然后,您可以 filter
对于刺激 A 或 B 为 1 且后跟等于 1 的响应的行。
df$Date <- as.POSIXct(strptime(df$Date,"%d.%m.%Y %H:%M"))
df %>%
arrange(User,Date)%>%
mutate(difftime= difftime(lead(Date),Date, units = "mins") ) %>%
group_by(User)%>%
filter((StimuliA==1 | StimuliB==1) & lead(Responses)==1)
User Date Hour StimuliA StimuliB Responses difftime
<chr> <dttm> <int> <int> <int> <int> <time>
1 005b98f3-5b1b-4d10-bdea-a55d012b2844 2015-11-25 13:59:00 1645 1 0 0 11253 mins
2 005b98f3-5b1b-4d10-bdea-a55d012b2844 2015-12-07 08:18:00 1928 1 0 0 2122 mins
3 005b98f3-5b1b-4d10-bdea-a55d012b2844 2015-12-08 19:40:00 1963 0 1 0 19510 mins
4 005b98f3-5b1b-4d10-bdea-a55d012b2844 2016-01-05 11:35:00 2627 0 1 0 106 mins
5 005b98f3-5b1b-4d10-bdea-a55d012b2844 2016-01-06 09:18:00 2649 1 0 0 56969 mins