如何为除了2个变量之外的所有变量匹配的案例子集数据框?

时间:2018-11-21 04:20:55

标签: r dplyr

我正在处理一个数据集,其中一部分参与者重复了某些条件组合。我想创建一个仅包含两个重复条件的单个数据集,以便检查可靠性和一致性。因此,最终数据集将只包含已完成两次的主题和条件,因此具有第一个重复值和第二个重复值。

示例数据:

Data <- structure(list(Sub = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L), .Label = c("1", "2", "4", "7", "8", "9", "10", "11", "12", 
"13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"
), class = "factor"), Sys = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 
1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 
1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L
), Samp = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("T1", 
"T2", "T3", "T4"), class = "factor"), Cond = c("A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", 
"C", "D", "D", "D", "D", "D", "D", "D", "D", "E", "E", "E", "E", 
"E", "E", "E", "E", "C", "C", "C", "C", "C", "C", "C", "C", "D", 
"D", "D", "D", "D", "D", "D", "D", "E", "E", "E", "E", "E", "E", 
"E", "E", "C", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", 
"D", "D", "D", "D", "D", "E", "E", "E", "E", "E", "E", "E", "E", 
"C", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", 
"D", "D", "D", "C", "C", "C", "C", "C", "C", "C", "C", "D", "D", 
"D", "D", "D", "D", "D", "D", "C", "C", "C", "C", "C", "C", "C", 
"C", "D", "D", "D", "D", "D", "D", "D", "D"), Rep = c(1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L), Score = c(92.6666666666667, 77.6666666666667, 
106.333333333333, 47.3333333333333, 70.3333333333333, 48.6666666666667, 
96.6666666666667, 51.6666666666667, 80.3333333333333, 55.3333333333333, 
55.6666666666667, 22.3333333333333, 71.6666666666667, 31.6666666666667, 
74.3333333333333, 15.6666666666667, 67.3333333333333, 48.6666666666667, 
54.6666666666667, 41.3333333333333, 74, 54, 97, 72.3333333333333, 
26.625, 7.5, 5.25, -1.5, 6, -33, -8.25000000000001, -32.25, 19.875, 
4.5, 9.75, 5.625, -16.5, -21, 18.375, -16.5, -16.875, -18, -18.375, 
0.375, 0, 0, -17.25, -18, 68.3333333333333, 51, 102, 85.3333333333333, 
64.3333333333333, 50.3333333333333, 93.3333333333333, 104.333333333333, 
27, 76, 50, 44, 81, 91, 59.3333333333333, 91.6666666666667, 80.6666666666667, 
32.6666666666667, 96, 67, 42.3333333333333, 49.3333333333333, 
71, 63.3333333333333, 59, 47.3333333333333, 70.3333333333333, 
67.3333333333333, 56.3333333333333, 60.3333333333333, 115.333333333333, 
112.333333333333, 36.3333333333333, 80.3333333333333, 40.3333333333333, 
97, 87, 100.333333333333, 61.6666666666667, 104, 71, 28.6666666666667, 
88, 29.6666666666667, 47.6666666666667, 25.6666666666667, 62.6666666666667, 
35.6666666666667, 109, 66.3333333333333, 112, 39.6666666666667, 
69.6666666666667, 98.3333333333333, 74, 40.6666666666667, 47.3333333333333, 
75.6666666666667, 43.6666666666667, 74.3333333333333, 43, 75, 
39, 73.6666666666667, 68.6666666666667, 36.3333333333333, 107.666666666667, 
41, 98.6666666666667, 65.6666666666667, 74.6666666666667, 75.6666666666667, 
68.3333333333333, 68.3333333333333, 41, 51, 100, 102, 78, 85.3333333333333, 
36.3333333333333, 27, 88, 76, 45.3333333333333, 50, 37, 44, 37.3333333333333, 
59, 34.3333333333333, 47.3333333333333, 72.3333333333333, 70.3333333333333, 
67.6666666666667, 67.3333333333333, 56, 36.3333333333333, 83.3333333333333, 
80.3333333333333, 61, 40.3333333333333, 78.6666666666667, 97, 
67.6666666666667, 109, 67.3333333333333, 66.3333333333333, 97, 
112, 70.6666666666667, 39.6666666666667, 40.3333333333333, 47.3333333333333, 
95, 75.6666666666667, 71.6666666666667, 43.6666666666667, 72.6666666666667, 
74.3333333333333)), class = "data.frame", row.names = c(NA, -168L
))

如果仅查看重复条件的行数,我会看到24个观察值:

Data %>% 
    filter(Rep == 2) %>%
    nrow()
[1] 24

如果我仅看初次代表,就会看到144个观察结果:

Data %>% 
    filter(Rep == 1) %>%
    nrow()
[1] 144

如果我尝试使用_join中的dplyr函数,我得到的不仅仅是匹配的案例;我返回了48行:

Joined_Data <- right_join(Data %>% 
                 filter(Rep == 1) %>%
                 rename("Score_1" = Score) %>%
                 select(-Rep),
               Data %>% 
                 filter(Rep == 2) %>%
                 rename("Score_2" = Score) %>%
                 select(-Rep),
               by = c("Sub", "Sys", "Samp", "Cond")) 


nrow(Joined_Data)
[1] 48

这似乎是因为每一行都是重复的:

head(Joined_Data)
  Sub Sys Samp Cond   Score_1   Score_2
1   1   1   T1    C  68.33333  68.33333
2   1   1   T1    C  68.33333  68.33333
3   1   2   T1    C  51.00000  41.00000
4   1   2   T1    C  51.00000  41.00000
5   1   1   T2    C 102.00000 100.00000
6   1   1   T2    C 102.00000 100.00000

我可以通过将小标题通过distinct()来删除重复项,但是这种方法看起来很混乱。

通过distinct()传递上述内容确实会给出所需的输出

Joined_Data <- right_join(Data %>% 
                     filter(Rep == 1) %>%
                     rename("Score_1" = Score) %>%
                     select(-Rep),
                   Data %>% 
                     filter(Rep == 2) %>%
                     rename("Score_2" = Score) %>%
                     select(-Rep),
                   by = c("Sub", "Sys", "Samp", "Cond")) %>%
                 distinct()

   Sub Sys Samp Cond   Score_1   Score_2
1    1   1   T1    C  68.33333  68.33333
2    1   2   T1    C  51.00000  41.00000
3    1   1   T2    C 102.00000 100.00000
4    1   2   T2    C  85.33333  78.00000
5    1   1   T1    D  27.00000  36.33333
6    1   2   T1    D  76.00000  88.00000
7    1   1   T2    D  50.00000  45.33333
8    1   2   T2    D  44.00000  37.00000
9    7   1   T1    C  59.00000  37.33333
10   7   2   T1    C  47.33333  34.33333
11   7   1   T2    C  70.33333  72.33333
12   7   2   T2    C  67.33333  67.66667
13   7   1   T1    D  36.33333  56.00000
14   7   2   T1    D  80.33333  83.33333
15   7   1   T2    D  40.33333  61.00000
16   7   2   T2    D  97.00000  78.66667
17  11   1   T1    C 109.00000  67.66667
18  11   2   T1    C  66.33333  67.33333
19  11   1   T2    C 112.00000  97.00000
20  11   2   T2    C  39.66667  70.66667
21  11   1   T1    D  47.33333  40.33333
22  11   2   T1    D  75.66667  95.00000
23  11   1   T2    D  43.66667  71.66667
24  11   2   T2    D  74.33333  72.66667

然后我可以gather将该小标题变回长格式:

所需的输出:

Joined_Data %>%
    gather(Rep, Rating, Rating_1:Rating_2) %>%
      separate(Rep, c(NA, "Rep"), sep = "_", remove = T )

       Sub Sys Samp Cond Rep     Score
    1    1   1   T1    C   1  68.33333
    2    1   2   T1    C   1  51.00000
    3    1   1   T2    C   1 102.00000
    4    1   2   T2    C   1  85.33333
    5    1   1   T1    D   1  27.00000
    6    1   2   T1    D   1  76.00000
    7    1   1   T2    D   1  50.00000
    8    1   2   T2    D   1  44.00000
    9    7   1   T1    C   1  59.00000
    10   7   2   T1    C   1  47.33333
    11   7   1   T2    C   1  70.33333
    12   7   2   T2    C   1  67.33333
    13   7   1   T1    D   1  36.33333
    14   7   2   T1    D   1  80.33333
    15   7   1   T2    D   1  40.33333
    16   7   2   T2    D   1  97.00000
    17  11   1   T1    C   1 109.00000
    18  11   2   T1    C   1  66.33333
    19  11   1   T2    C   1 112.00000
    20  11   2   T2    C   1  39.66667
    21  11   1   T1    D   1  47.33333
    22  11   2   T1    D   1  75.66667
    23  11   1   T2    D   1  43.66667
    24  11   2   T2    D   1  74.33333
    25   1   1   T1    C   2  68.33333
    26   1   2   T1    C   2  41.00000
    27   1   1   T2    C   2 100.00000
    28   1   2   T2    C   2  78.00000
    29   1   1   T1    D   2  36.33333
    30   1   2   T1    D   2  88.00000
    31   1   1   T2    D   2  45.33333
    32   1   2   T2    D   2  37.00000
    33   7   1   T1    C   2  37.33333
    34   7   2   T1    C   2  34.33333
    35   7   1   T2    C   2  72.33333
    36   7   2   T2    C   2  67.66667
    37   7   1   T1    D   2  56.00000
    38   7   2   T1    D   2  83.33333
    39   7   1   T2    D   2  61.00000
    40   7   2   T2    D   2  78.66667
    41  11   1   T1    C   2  67.66667
    42  11   2   T1    C   2  67.33333
    43  11   1   T2    C   2  97.00000
    44  11   2   T2    C   2  70.66667
    45  11   1   T1    D   2  40.33333
    46  11   2   T1    D   2  95.00000
    47  11   1   T2    D   2  71.66667
    48  11   2   T2    D   2  72.66667

这似乎是很多笨拙的步骤,所以我想知道是否有一种更有效的方法来将数据子集化,使其仅包含具有2分的特定案例(第一个代表一个,第二个代表一个)并忽略/删除只有1个代表/得分的案例。

是否有一种更清洁/更好的方法来完成上述任务?

2 个答案:

答案 0 :(得分:0)

如果我正确地得到了您想要的东西,我相信这可以解决问题:

Data <- Data %>% unique()

Data %>% 
  group_by(Sub, Sys, Samp, Cond) %>%      # check the number of rows for each combination of Sub, Sys, Samp and Cond
  summarise(cnt = n()) %>% 
  filter(cnt > 1) %>%          # filter out groups with just one row and then remove the count column 
  select(-cnt) %>%         
  left_join(Data, by = c('Sub', 'Sys', 'Samp', 'Cond')) 

答案 1 :(得分:0)

如果我理解正确,这就是您想要的。

注意:我要使用data.table方法,也可以为dplyr进行修改,尽管对我来说,一个简单的合并似乎比那些长管道还干净:)

require(data.table); require(magrittr)
Data <- as.data.table(Data)

merge(x = Data[ Rep == 1, .(Sub, Sys, Samp, Cond, Score)] %>% .[!duplicated(.), ],
      y = Data[ Rep == 2, .(Sub, Sys, Samp, Cond, Score)],
      by = c('Sub', 'Sys', 'Samp', 'Cond'),
      all.y = T, suffixes = c('_1', '_2'))