如何判断时间编码数据是否落入时间范围?
How do I determine whether time-coded data falls into time range?
我一直在尝试编写一个for循环以确定我的时间数据是否在特定时间范围内。我已经解决了所有关于堆栈溢出的相关问题,到目前为止,这是我得到的:
基本上,我有一个包含元音声学测量值的数据框。对于每个元音,我还有参与者说出元音的时间(以秒为单位)。
然后我有第二个数据框,包括时间间隔。这些间隔对应于参与者说话的时间段,并且没有重叠的噪音。因此,这些间隔从我的第一个数据帧中识别出可用于后续分析的元音,因为它们的声学测量没有被其他噪音污染
我需要在数据框 1 中创建一个新列(“目标”),用于指示每个参与者和每个记录的元音是否属于数据框 2 的间隔之一。
这些是数据框 1 中感兴趣的变量:
Participant RecordingNumber time
1 FSO110 1 37.258
2 FSO110 1 37.432
3 FSO110 1 37.496
4 FSO110 1 38.138
5 FSO110 1 38.499
6 FSO110 1 42.124
7 FSO110 1 61.733
8 FSO110 1 61.924
9 FSO110 1 61.980
10 FSO110 1 62.260
11 FSO110 1 62.610
12 FSO110 1 62.943
13 FSO110 1 194.929
14 FSO110 1 195.403
15 FSO110 1 401.114
16 FSO110 1 401.341
这些是数据框 2 中感兴趣的变量:
Participant RecordingNumber tmin tmax
FSO110 1 445.695 447.250
FSO110 1 448.444 449.093
FSO110 1 452.990 453.292
FSO110 1 481.177 481.709
FSO110 2 41.202 41.511
FSO110 2 42.176 43.132
FSO110 2 44.640 47.710
FSO110 2 53.819 56.253
FSO110 2 113.453 114.803
FSO110 2 123.135 123.374
到目前为止,我已经到达那里:
# split dataframes by Participant and Recording Number
data1 <- split(data1, paste0(data1$Participant, data1$RecordingNumber))
data2 <- split(data2, paste0(data2$Participant, data2$RecordingNumber))
# loop through each element of each splitted df
for (n in seq_along(data1)){
for (m in seq_along(data2)){
if(n == m){
data_split[[n]][["target"]] = as.character(lapply(data1[[n]][["time"]], FUN = function(x){
for (i in 1:nrow(data2[[m]])){
if(data2[[m]][["tmin"]]<=x & x<= data2[[m]][["tmax"]]){
return(paste0("in"))}
else{
return(paste0("overlap"))}
}
}
))}
}
该功能似乎有效。但是,它仅适用于 i == 1(数据行 2)。因此,它正确地识别了数据 1 中的时间点,这些时间点落入数据 2 的每个拆分元素的第一个间隔,但不会继续其他间隔。
我尝试过的解决方案:
- 使用 ifelse 代替 if 语句
for (n in seq_along(data1)){
for (m in seq_along(data2)){
if (n == m){
data1[[n]][["target"]] = as.character(lapply(data1[[n]][["time"]], FUN = function(x){
for (i in 1:nrow(data2[[m]])){
ifelse((data2[[m]][["tmin"]]<=x & x<= data2[[m]][["tmax"]]), "in", "overlap")
}
}
))}}
}
但是,对于我的新“目标列”的每一行,此函数 returns NULL。
- 将 any() 添加到我的 if 语句中:
for (n in seq_along(data_split)){
for (m in seq_along(data_split_target)){
if(n == m) {
data_split[[n]][["target"]] = as.character(lapply(data_split[[n]][["time"]], FUN = function(x){
for (i in 1:nrow(data_split_target[[m]])){
if(any(data_split_target[[m]][["tmin"]])<=x & any(x<= data_split_target[[m]][["tmax"]])){
return(paste0("in"))}
else{
return(paste0("overlap"))}
}
}
))}
}
同样,该函数似乎可以正常工作,因为它正确地创建了一个包含“in”和“overlap”行的新“target”列,但函数错误地returns“in”行值,即使时间点没有落入其中一个区间。
有人可以帮助我吗?非常感谢!
这是使用 split/Map
的基础 R 方法。
拆分数据集,然后 Map
将函数 f
应用于每个子 df。
meas_split <- split(measures, list(measures$Participant, measures$RecordingNumber))
int_split <- split(intervals, list(intervals$Participant, intervals$RecordingNumber))
nms <- intersect(names(meas_split), names(int_split))
i <- match(names(meas_split[nms]), names(int_split[nms]))
j <- match(names(int_split[nms]), names(meas_split[nms]))
f <- function(X, Y){
yes <- sapply(X[["time"]], \(x){
x > Y[["tmin"]] & x < Y[["tmax"]]
})
as.integer(colSums(yes) > 0)
}
measures$target <- unlist(Map(f, meas_split[i], int_split[j]))
使用 sqldf 包解决了它。
result_all = sqldf("select * from data1
left join data2
on data1.rec = data2.rec
and data1.time between data2.tmin and data2.tmax")
其中 $rec 是标识参与者和记录编号的分组变量。
我一直在尝试编写一个for循环以确定我的时间数据是否在特定时间范围内。我已经解决了所有关于堆栈溢出的相关问题,到目前为止,这是我得到的:
基本上,我有一个包含元音声学测量值的数据框。对于每个元音,我还有参与者说出元音的时间(以秒为单位)。
然后我有第二个数据框,包括时间间隔。这些间隔对应于参与者说话的时间段,并且没有重叠的噪音。因此,这些间隔从我的第一个数据帧中识别出可用于后续分析的元音,因为它们的声学测量没有被其他噪音污染
我需要在数据框 1 中创建一个新列(“目标”),用于指示每个参与者和每个记录的元音是否属于数据框 2 的间隔之一。
这些是数据框 1 中感兴趣的变量:
Participant RecordingNumber time
1 FSO110 1 37.258
2 FSO110 1 37.432
3 FSO110 1 37.496
4 FSO110 1 38.138
5 FSO110 1 38.499
6 FSO110 1 42.124
7 FSO110 1 61.733
8 FSO110 1 61.924
9 FSO110 1 61.980
10 FSO110 1 62.260
11 FSO110 1 62.610
12 FSO110 1 62.943
13 FSO110 1 194.929
14 FSO110 1 195.403
15 FSO110 1 401.114
16 FSO110 1 401.341
这些是数据框 2 中感兴趣的变量:
Participant RecordingNumber tmin tmax
FSO110 1 445.695 447.250
FSO110 1 448.444 449.093
FSO110 1 452.990 453.292
FSO110 1 481.177 481.709
FSO110 2 41.202 41.511
FSO110 2 42.176 43.132
FSO110 2 44.640 47.710
FSO110 2 53.819 56.253
FSO110 2 113.453 114.803
FSO110 2 123.135 123.374
到目前为止,我已经到达那里:
# split dataframes by Participant and Recording Number
data1 <- split(data1, paste0(data1$Participant, data1$RecordingNumber))
data2 <- split(data2, paste0(data2$Participant, data2$RecordingNumber))
# loop through each element of each splitted df
for (n in seq_along(data1)){
for (m in seq_along(data2)){
if(n == m){
data_split[[n]][["target"]] = as.character(lapply(data1[[n]][["time"]], FUN = function(x){
for (i in 1:nrow(data2[[m]])){
if(data2[[m]][["tmin"]]<=x & x<= data2[[m]][["tmax"]]){
return(paste0("in"))}
else{
return(paste0("overlap"))}
}
}
))}
}
该功能似乎有效。但是,它仅适用于 i == 1(数据行 2)。因此,它正确地识别了数据 1 中的时间点,这些时间点落入数据 2 的每个拆分元素的第一个间隔,但不会继续其他间隔。
我尝试过的解决方案:
- 使用 ifelse 代替 if 语句
for (n in seq_along(data1)){
for (m in seq_along(data2)){
if (n == m){
data1[[n]][["target"]] = as.character(lapply(data1[[n]][["time"]], FUN = function(x){
for (i in 1:nrow(data2[[m]])){
ifelse((data2[[m]][["tmin"]]<=x & x<= data2[[m]][["tmax"]]), "in", "overlap")
}
}
))}}
}
但是,对于我的新“目标列”的每一行,此函数 returns NULL。
- 将 any() 添加到我的 if 语句中:
for (n in seq_along(data_split)){
for (m in seq_along(data_split_target)){
if(n == m) {
data_split[[n]][["target"]] = as.character(lapply(data_split[[n]][["time"]], FUN = function(x){
for (i in 1:nrow(data_split_target[[m]])){
if(any(data_split_target[[m]][["tmin"]])<=x & any(x<= data_split_target[[m]][["tmax"]])){
return(paste0("in"))}
else{
return(paste0("overlap"))}
}
}
))}
}
同样,该函数似乎可以正常工作,因为它正确地创建了一个包含“in”和“overlap”行的新“target”列,但函数错误地returns“in”行值,即使时间点没有落入其中一个区间。
有人可以帮助我吗?非常感谢!
这是使用 split/Map
的基础 R 方法。
拆分数据集,然后 Map
将函数 f
应用于每个子 df。
meas_split <- split(measures, list(measures$Participant, measures$RecordingNumber))
int_split <- split(intervals, list(intervals$Participant, intervals$RecordingNumber))
nms <- intersect(names(meas_split), names(int_split))
i <- match(names(meas_split[nms]), names(int_split[nms]))
j <- match(names(int_split[nms]), names(meas_split[nms]))
f <- function(X, Y){
yes <- sapply(X[["time"]], \(x){
x > Y[["tmin"]] & x < Y[["tmax"]]
})
as.integer(colSums(yes) > 0)
}
measures$target <- unlist(Map(f, meas_split[i], int_split[j]))
使用 sqldf 包解决了它。
result_all = sqldf("select * from data1
left join data2
on data1.rec = data2.rec
and data1.time between data2.tmin and data2.tmax")
其中 $rec 是标识参与者和记录编号的分组变量。