删除不匹配的主题 R

delete subjects that are not matched R

我有一个这样的 df :

ID  matching_variable   status
 1     1                 case
 2     1                 control
 3     2                 case
 4     2                 case
 5     3                 control
 6     3                 control
 7     4                 case
 8     4                 control
 9     5                 case
10     6                 control

我想保留所有匹配(具有相同匹配变量)且有 1 个案例和 1 个对照(例如对应于匹配变量 = 1 或加工变量 = 4)

所以,我想删除只有案例(例如matching_variable =2)或只有对照(例如matching_variable =3)的匹配主题和单独(未匹配)(如最后2个科目)

预期的结果是这样的:

 ID matching_variable   status
  1         1           case
  2         1           control
  7         4           case
  8         4           control

我确定它不会太复杂,但我不知道该怎么做...

在此先感谢您的帮助

试试这个方法:

library(tidyverse)

tribble(
  ~ID, ~matching_variable, ~status,
  1, 1, "case",
  2, 1, "control",
  3, 2, "case",
  4, 2, "case",
  5, 3, "control",
  6, 3, "control",
  7, 4, "case",
  8, 4, "control",
  9, 5, "case",
  10, 6, "control"
) |> 
  group_by(matching_variable) |> 
  filter(first(status) != last(status))
#> # A tibble: 4 × 3
#> # Groups:   matching_variable [2]
#>      ID matching_variable status 
#>   <dbl>             <dbl> <chr>  
#> 1     1                 1 case   
#> 2     2                 1 control
#> 3     7                 4 case   
#> 4     8                 4 control

reprex package (v2.0.1)

于 2022-04-28 创建

来自 base R 的想法,

df[as.logical(with(df, ave(status, matching_variable, FUN = function(i)length(unique(i)) > 1))),]

  ID matching_variable  status
1  1                 1    case
2  2                 1 control
7  7                 4    case
8  8                 4 control

另一个可能的解决方案:

library(tidyverse)

df %>% 
  group_by(matching_variable) %>% 
  mutate(n = n_distinct(status)) %>% 
  ungroup %>% 
  filter(n > 1) %>% 
  select(-n)

#> # A tibble: 4 × 3
#>      ID matching_variable status 
#>   <int>             <int> <chr>  
#> 1     1                 1 case   
#> 2     2                 1 control
#> 3     7                 4 case   
#> 4     8                 4 control

使用 tidyverse...

library(dplyr)

df %>% 
    group_by(matching_variable) %>% 
    filter(length(unique(status)) == 2 & length(status) == 2)

     ID matching_variable status 
  <int>             <int> <chr>  
1     1                 1 case   
2     2                 1 control
3     7                 4 case   
4     8                 4 control

过滤器确保每个分组的匹配变量中恰好有两种不同的类型,但总共不超过两个条目(例如,如果你有两个案例和一个控制,我认为你会想要拒绝)。

这里还有一个:

library(dplyr)

df %>%
   group_by(matching_variable) %>%
   filter(n() == 2 & 
            !duplicated(status) &
            (!duplicated(status, fromLast = TRUE)))
     ID matching_variable status 
  <int>             <int> <chr>  
1     1                 1 case   
2     2                 1 control
3     7                 4 case   
4     8                 4 control