这个问题是对此的后续:根据个人注视计算相互注视。
我正在研究传统对话中问答序列中的注视数据,想知道何时以及持续多长时间出现相互注视,即一个人看着另一个人,另一个人也看着另一个人。上一个问题的答案很好地处理了只有说话者和听众之间相互注视的问答序列,但它无法处理两个听众之间也相互注视的情况。
我拥有的数据类型如下所示:
GazeID Sequ Utterance Q_by Answ_by Gaze_by Gaze_to Role start end Gaze_pair
1: 1 55 where...? A B A B Speaker 100 700 AB
2: 2 55 where...? A B B A Answerer 0 200 AB
3: 3 55 where...? A B B C Answerer 230 500 BC
4: 4 55 where...? A B C B NonAnswerer 120 620 BC
5: 5 55 where...? A B C A NonAnswerer 650 700 AC
这里,和 之间有相互注视(i)Speaker
,而且和 之间Answerer
也有相互注视,因此所需的输出是这样的:Answerer
NonAnswerer
Sequ Utterance MG_start MG_end MG_dur Gaze_pair
1: 55 where...? 100 200 100 AB
2: 55 where...? 230 500 270 BC
data.table
我尝试将基于函数构建的上一个问题的解决方案应用foverlaps
到这个场景,但收到了错误。
注意:在任何一个问答序列中,可以有多次相互注视,并且可以有 (i) Speaker_Answerer
、(ii)Speaker-NonAnswerer
和 (iii)之间的相互注视Answerer-NonAnswerer
。
任何关于此问题的帮助都将不胜感激。
可重复的数据:
gazes <- structure(list(GazeID = 1:5, Sequ = c(55, 55, 55, 55, 55), Utterance = c("where...?",
"where...?", "where...?", "where...?", "where...?"), Q_by = c("A",
"A", "A", "A", "A"), Answ_by = c("B", "B", "B", "B", "B"), Gaze_by = c("A",
"B", "B", "C", "C"), Gaze_to = c("B", "A", "C", "B", "A"), Role = c("Speaker",
"Answerer", "Answerer", "NonAnswerer", "NonAnswerer"), start = c(100L,
0L, 230L, 120L, 650L), end = c(700L, 200L, 500L, 620L, 700L),
Gaze_pair = c("AB", "AB", "BC", "BC", "AC")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -5L))
一种方法是将数据按凝视对拆分为数据框列表,并计算该列表中的每个数据框的相互凝视。这用于
data.table::foverlaps()
快速重叠连接。如您所愿,dplyr
它的编写方式是将其插入到其分组函数中,该函数接受并返回数据框,具体来说dplyr::group_modify()
。然后只需计算所有相互注视对即可:
关于多次凝视的说明
请注意使用
pmin()
andpmax()
而不是min()
andmax()
。在您的示例数据中,每个话语都有一次相互凝视。例如,A
看着B
从100
到700
,而 B 看着A
从0
到,因此从到200
重叠。但是,如果我们想象那个人再次看着那个人从到,我们每个话语就会有两次相互凝视。这种方法在这种情况下会起作用:100
200
B
A
300
400
包括没有凝视的序列
回应您的评论,询问如何确保所有
Sequ
ence 都包括在内,即使它们没有相互注视,该函数也不知道每个 enceSequ
是否以前有过相互注视。我认为最简单的方法是事后加入任何缺失的序列,而不是引入状态。首先,让我们添加一个新的Sequ
,66
,没有相互注视:然后我们可以检查哪些
Sequ
ence 未包含在输出中并将它们与所有其他值一起添加NA
:请注意,我们需要
%>%
而不是 ,因为我们需要在不允许使用基本管道等效项的地方|>
使用管道占位符。无论如何,此连接可确保 的所有值都有一行。.
_
Sequ