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

时间:2017-04-04 20:43:03

标签: r dplyr tidyr

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

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

3 个答案:

答案 0 :(得分:4)

假设您的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

答案 1 :(得分:3)

一种方法是使用tidy::expand()生成studypersonid的所有可能组合,然后使用anti_join()删除实际出现在数据中的组合。< / p>

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

答案 2 :(得分:2)

使用基础R的简单解决方案

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

输出:

$x
integer(0)

$y
[1] 2 5