首页 > 解决方案 > 使用组外的组合完成组内的数据框

问题描述

我需要在组内添加缺失的变量组合,但使用该组外的组合。举个例子。这是一个数据框,评估者查看样本,然后回答关于样本的三个问题。评分者 A 看了样本 1、2 和 3,而评分者 B 只查看了样本 1 和 2。还要注意,评分者 B 只完成了样本 1 的项目 7060 和 7930,但没有完成项目 7842。我想转即隐式缺失项目评分转化为显式缺失。目标是为样本中缺失的项目添加行,但不添加评估者中缺失的样本(即,不要将样本 3 添加到评估者 B,但将缺失的项目添加到评估者 B 评级的样本中)。

library(tidyverse)

df <- data_frame(
  rater_id = c(rep("A", 9), rep("B", 5)),
  sample_id = c(rep(1, 3), rep(2, 3), rep(3, 3), rep(1, 2), rep(2, 3)),
  item_id = c(7060, 7842, 7930, 9571, 4678, 5966, 1758, 3148, 2574,
              7060, 7930, 9571, 4678, 5966),
  score = sample(c(0, 1), size = 14, replace = TRUE)
)
df
#> # A tibble: 14 x 4
#>    rater_id sample_id item_id score
#>    <chr>        <dbl>   <dbl> <dbl>
#>  1 A                1    7060     0
#>  2 A                1    7842     0
#>  3 A                1    7930     1
#>  4 A                2    9571     0
#>  5 A                2    4678     0
#>  6 A                2    5966     1
#>  7 A                3    1758     0
#>  8 A                3    3148     1
#>  9 A                3    2574     0
#> 10 B                1    7060     0
#> 11 B                1    7930     0
#> 12 B                2    9571     0
#> 13 B                2    4678     1
#> 14 B                2    5966     1

我尝试使用tidy::complete但收效甚微。嵌套sample_idanditem_id不会添加缺失的行,因为sample_idand的所有组合item_id都已经存在于数据中。

df %>% complete(nesting(sample_id, item_id))
#> # A tibble: 14 x 4
#>    sample_id item_id rater_id score
#>        <dbl>   <dbl> <chr>    <dbl>
#>  1         1    7060 A            0
#>  2         1    7060 B            0
#>  3         1    7842 A            0
#>  4         1    7930 A            1
#>  5         1    7930 B            0
#>  6         2    4678 A            0
#>  7         2    4678 B            1
#>  8         2    5966 A            1
#>  9         2    5966 B            1
#> 10         2    9571 A            0
#> 11         2    9571 B            0
#> 12         3    1758 A            0
#> 13         3    2574 A            0
#> 14         3    3148 A            1

在嵌套语句之外添加rater_id也无法提供所需的输出。它成功地为样本 1 添加了缺失的行,但也为样本 3 添加了额外的缺失行。但是,由于从未给过评估者 B 样本 3,因此我们不会将其视为“缺失”(尽管从技术上讲它是这样) .

df %>% complete(rater_id, nesting(sample_id, item_id))
#> # A tibble: 18 x 4
#>    rater_id sample_id item_id score
#>    <chr>        <dbl>   <dbl> <dbl>
#>  1 A                1    7060     0
#>  2 A                1    7842     0
#>  3 A                1    7930     1
#>  4 A                2    4678     0
#>  5 A                2    5966     1
#>  6 A                2    9571     0
#>  7 A                3    1758     0
#>  8 A                3    2574     0
#>  9 A                3    3148     1
#> 10 B                1    7060     0
#> 11 B                1    7842    NA
#> 12 B                1    7930     0
#> 13 B                2    4678     1
#> 14 B                2    5966     1
#> 15 B                2    9571     0
#> 16 B                3    1758    NA
#> 17 B                3    2574    NA
#> 18 B                3    3148    NA

我的理想输出如下所示:

#> # A tibble: 18 x 4
#>    rater_id sample_id item_id score
#>    <chr>        <dbl>   <dbl> <dbl>
#>  1 A                1    7060     0
#>  2 A                1    7842     0
#>  3 A                1    7930     1
#>  4 A                2    4678     0
#>  5 A                2    5966     1
#>  6 A                2    9571     0
#>  7 A                3    1758     0
#>  8 A                3    2574     0
#>  9 A                3    3148     1
#> 10 B                1    7060     0
#> 11 B                1    7842    NA
#> 12 B                1    7930     0
#> 13 B                2    4678     1
#> 14 B                2    5966     1
#> 15 B                2    9571     0

标签: rdplyrtidyversetidyr

解决方案


这有点难看,但是您可以使用最后一次尝试(在嵌套语句之外添加 rater_id),然后删除根本不存在评估者样本对的情况。可能有几种方法可以做到这一点,但这个似乎工作:

df %>% 
  complete(rater_id, nesting(sample_id, item_id)) %>% # This was your approach
  group_by(rater_id, sample_id) %>% 
  mutate(count_non_nas = sum(!is.na(score))) %>% # Count up the number of non-NA scores
  filter(count_non_nas > 0) %>% # Remove cases where ALL the scores in a group are NA
  select(-count_non_nas) %>% # Drop the intermediate column
  ungroup()

df

# A tibble: 15 x 4
   rater_id sample_id item_id score
   <chr>        <dbl>   <dbl> <dbl>
 1 A                1    7060     1
 2 A                1    7842     0
 3 A                1    7930     0
 4 A                2    4678     0
 5 A                2    5966     0
 6 A                2    9571     0
 7 A                3    1758     0
 8 A                3    2574     0
 9 A                3    3148     0
10 B                1    7060     1
11 B                1    7842    NA
12 B                1    7930     1
13 B                2    4678     0
14 B                2    5966     1
15 B                2    9571     0

推荐阅读