R-为每个组有效地计算二进制变量中的开关数量

时间:2018-06-30 13:09:26

标签: r

为了提供一些背景信息,我有一个心理学实验眼动数据的数据框,我想为每个参与者计算两个兴趣区域(AOI)之间的切换。

这是问题的简化数据框(我们假设AOI2 == !AOI1是不需要的):

library(tidyverse)

df <- tibble(Participant = rep(1:7, times = 1, each = 10),
             Time = rep(1:10, 7),
             AOI1 = rbinom(70, 1, .5))

我要计算的是AOI1的值在每个参与者的时间内变化了多少次。我可以使用像波纹管这样的for循环来做到这一点,但是我想知道是否有一种更简单,更R的方式来做到这一点?

df.switches <- tibble(Participant = 1:7,
                      Switches = NA)
for(p in 1:7){
  s <- 0
  for(i in 2:10){
    if(subset(df, Participant == p & Time == i, select = AOI1) !=
       subset(df, Participant == p & Time == i-1, select = AOI1)){
      s <- s + 1
    }
  }
  df.switches <- df.switches %>%
    mutate(Switches = ifelse(Participant == p, s, Switches))
}

2 个答案:

答案 0 :(得分:4)

一种选择是使用dplyr::lag将值与当前行进行比较,以便为每个参与者计算开关的数量。

library(tidyverse)

df %>% group_by(Participant) %>%
  summarise(count = sum(AOI1 != lag(AOI1, default = -Inf)))

# # A tibble: 7 x 2
#   Participant count
#         <int> <int>
# 1           1     5
# 2           2     4
# 3           3     5
# 4           4     4
# 5           5     6
# 6           6     6
# 7           7     4

答案 1 :(得分:1)

由于您已经在使用tidyverse,所以可以使用lag作为dplyr的一部分。这将检查AOI1的值是否与先前的值相同,如果不相同,则将标志设置为1。对于每个参与者的第一条记录,该值自动设置为NA。请注意,group_by是必需的,否则,每次遇到新的参与者时,该标志都不会“重置”。还假定数据按参与者和时间排序;如果不是,则在arrange(Participant, Time)之前用管道group_by

df <- tibble(Participant = rep(1:7, times = 1, each = 10),
             Time = rep(1:10, 7),
             AOI1 = rbinom(70, 1, .5))
df2 <- df %>%
  group_by(Participant) %>%
  mutate(switch = ifelse(AOI1 != lag(AOI1), 1, 0)) %>%
  summarise(num_switches = sum(switch, na.rm = TRUE))