R -如何按组标识非连续数值

h4cxqtbf  于 2023-09-27  发布在  其他
关注(0)|答案(2)|浏览(106)

我有一个很长的数据集,其中不同的受试者(用subj_id标识)注意到了由连续变量Trial_Nr标识的不同刺激。我想确定Trial_Nr序列被破坏的对象,以及破坏发生的地方。
这是一个MWE:

df <- structure(list(Crowdsourcing_SubjId = c("5e42fc295135b5000cd20d0b", 
"5e42fc295135b5000cd20d0b", "5e42fc295135b5000cd20d0b", "5e42fc295135b5000cd20d0b", 
"5e42fc295135b5000cd20d0b", "5e42fc295135b5000cd20d0b", "63bd9ac0dc52225142c5b1d4", 
"63bd9ac0dc52225142c5b1d4", "63bd9ac0dc52225142c5b1d4", "63bd9ac0dc52225142c5b1d4"
), Trial_Nr = c(1:6, 1, 2, 5, 6)), row.names = c(NA, 10L), class = "data.frame")

我发现了一些使用diff()的其他帖子,但由于某种原因,我无法按组使用它:

library(tidyverse)

df %>%
group_by(Crowsourcing_SubjId) %>%
summarise(flag = diff(Trial_Nr))

执行上述操作只会给予所有主题的行间差异,而不进行分组,也无法识别中断发生的位置。
下面是我想要得到的输出:

Crowdsourcing_SubjId      flag  disruption
5e42fc295135b5000cd20d0b  1     NA
63bd9ac0dc52225142c5b1d4  3     2
wwwo4jvm

wwwo4jvm1#

用于创建数据框而不是list的数据:

df <- data.frame(Crowdsourcing_SubjId = c("5e42fc295135b5000cd20d0b", 
"5e42fc295135b5000cd20d0b", "5e42fc295135b5000cd20d0b", "5e42fc295135b5000cd20d0b", 
"5e42fc295135b5000cd20d0b", "5e42fc295135b5000cd20d0b", "63bd9ac0dc52225142c5b1d4", 
"63bd9ac0dc52225142c5b1d4", "63bd9ac0dc52225142c5b1d4", "63bd9ac0dc52225142c5b1d4"
), Trial_Nr = c(1:6, 1, 2, 5, 6))

这将flag定义为按组连续值之间的最大差值,disruption定义为按组连续差值第一次大于1的位置。

library(dplyr)
df |>
  group_by(Crowdsourcing_SubjId) |>
  summarise(
    flag = max(diff(Trial_Nr)),
    disruption = match(TRUE, c(diff(Trial_Nr), 1) > 1)
  )
# # A tibble: 2 × 3
#   Crowdsourcing_SubjId      flag disruption
#   <chr>                    <dbl>      <int>
# 1 5e42fc295135b5000cd20d0b     1         NA
# 2 63bd9ac0dc52225142c5b1d4     3          2
kd3sttzy

kd3sttzy2#

使用diff是一个很好的开始,但你必须走得更远。您需要的是组中的连续行以1分隔。所以你需要将diffing的结果与1进行比较。
这里使用data.table包是一个部分解决方案。

library(data.table)
df <- data.table(df)

# compute pairwise difference between consecutive lines in a group
df[, by=Crowdsourcing_SubjId, flag := c(diff(Trial_Nr), 1)]

# select disruption size and position, added count to keep no disruption case
df[, by=Crowdsourcing_SubjId, .(
  count = sum(flag!=1),
  flag = flag[flag!=1], 
  disruption = which(flag!=1)
)]

结果如下

Crowdsourcing_SubjId count  flag disruption
                     <char> <int> <num>      <int>
1: 5e42fc295135b5000cd20d0b     0    NA         NA
2: 63bd9ac0dc52225142c5b1d4     1     3          2

与您所期望的略有不同。当没有中断时,返回的标志将是NA而不是1

相关问题