检查计数器变量中的步骤是否丢失

check whether steps in a counter variable are missing

我有一个数据文件,每个参与者一行(根据他们参与的研究命名为 1-x)。我想检查数据集中是否存在所有参与者。这是我的玩具数据集,personid 是参与者,study 是他们参与的研究。

df <- read.table(text = "personid study measurement
1         x     23
2         x     32
1         y     21
3         y     23
4         y     23
6         y     23", header=TRUE)

看起来像这样:

  personid study measurement
1        1    x          23
2        2    x          32
3        1    y          21
4        3    y          23
5        4    y          23
6        6    y          23

所以对于 y,我缺少参与者 2 和 5。我如何自动检查?我尝试添加一个计数器变量并将该计数器变量与参与者 ID 进行比较,但是一旦缺少一个参与者,比较就毫无意义,因为对齐已关闭。

df %>% group_by(study) %>% mutate(id = 1:n(),check = id==personid)
Source: local data frame [6 x 5]
Groups: date [2]

  personid   study measurement    id check
     <int> <fctr>       <int> <int> <lgl>
1        1      x          23     1  TRUE
2        2      x          32     2  TRUE
3        1      y          21     1  TRUE
4        3      y          23     2 FALSE
5        4      y          23     3 FALSE
6        6      y          23     4 FALSE

假设您的 personid 是连续的,那么您可以使用 setdiff 来做到这一点,即

library(dplyr)

df %>% 
 group_by(study) %>% 
 mutate(new = toString(setdiff(max(personid):min(personid), personid)))

#Source: local data frame [6 x 4]
#Groups: study [2]

#  personid  study measurement   new
#     <int> <fctr>       <int> <chr>
#1        1      x          23      
#2        2      x          32      
#3        1      y          21  5, 2
#4        3      y          23  5, 2
#5        4      y          23  5, 2
#6        6      y          23  5, 2

一种方法是使用tidy::expand()生成studypersonid的所有可能组合,然后使用anti_join()去除数据中实际出现的组合.

library(dplyr, warn.conflicts = FALSE)
library(tidyr)

df %>% 
  expand(study, personid) %>% 
  anti_join(df)
#> Joining, by = c("study", "personid")
#> # A tibble: 4 × 2
#>    study personid
#>   <fctr>    <int>
#> 1      y        2
#> 2      x        6
#> 3      x        4
#> 4      x        3

使用 base R 的简单解决方案

tapply(df$personid, df$study, function(a) setdiff(min(a):max(a), a))

输出:

$x
integer(0)

$y
[1] 2 5