识别和标记R中的部分重复记录

时间:2017-12-15 10:48:05

标签: r dataframe duplicates

我有一个包含数千(~12k)记录和多个(36)变量的数据框。为了提供一些背景,这些是对动物行为的观察。 20个变量记录了特定个体的存在与否(作为2个级别的因子)。

我想要实现的是创建一个附加变量,该变量标记存在/不存在变量的每个唯一组合。所以,如果我有以下简化数据集,那么X& Y记录感兴趣的变量(细节与问题无关)和三个人A,B,C(其中" ab" =缺席和" pr" =存在):

Date      Time    X    Y    A   B   C
17-12-01  10:15   2    4    pr  ab  pr
17-12-01  10:45   3    5    pr  ab  pr
17-12-01  11:15   2    4    ab  pr  pr
17-12-01  11:40   2    4    ab  pr  pr
17-12-01  11:15   6    7    ab  pr  ab
...

可能的独特组合是:

A    B    C
pr   pr   pr
pr   ab   ab
ab   pr   ab
ab   ab   pr
pr   pr   ab
ab   pr   pr
pr   ab   pr

[编辑:所有' ab'是 - 原则上 - 可能,但不会出现,因为所有人都缺席 - 因此无法进行观察]

[edit:]所需的输出:

Date      Time    X    Y    A   B   C     Combination
17-12-01  10:15   2    4    pr  ab  pr    1
17-12-01  10:45   3    5    pr  ab  pr    1
17-12-01  11:15   2    4    ab  pr  pr    2
17-12-01  11:40   2    4    ab  pr  pr    2
...                         ab  ab  pr    3    etc.  

我发现我可以使用distinct中的dplyr创建一个新的数据框,选择唯一的组合:

newDF = distinct(oldDF, A, B, C, .keep_all = TRUE)

但是这会删除(或者更确切地说不包括在newDF中)重复项,而我想要做的是保留所有重复项,但只标记每个独特的组合(所有其他帖子和建议我可以找到关注删除重复项,并且真正的数据框有20个个体'变量,而不仅仅是三个。

所以我的问题是:是否有办法使用 distinct 的输出来实现这一目标,或者让我自己陷入死胡同并需要另一种方法

任何帮助都非常感激。

尼克

3 个答案:

答案 0 :(得分:1)

使用dplyr的一种方法:

df %>% 
  mutate(id = group_indices(., A, B, C))

      Date  Time X Y  A  B  C id
1 17-12-01 10:15 2 4 pr ab pr  3
2 17-12-01 10:45 3 5 pr ab pr  3
3 17-12-01 11:15 2 4 ab pr pr  2
4 17-12-01 11:40 2 4 ab pr pr  2
5 17-12-01 11:15 6 7 ab pr ab  1
6 17-12-01 11:45 3 4 pr ab pr  3

答案 1 :(得分:1)

OP要求创建一个附加变量,用于标记存在/不存在变量的每个唯一组合。他提供了一个包含三个不同变量的样本数据集和一个三个变量值的可能组合表。

要获得 2 3 - 1 不同组合的不同数字,我们可以使用:

dt[, Combination := .GRP, by = .(A, B, C)][]

按外观顺序对组合进行编号(.GRPdata.table语法中的特殊符号):

       Date  Time X Y  A  B  C Combination
1: 17-12-01 10:15 2 4 pr ab pr           1
2: 17-12-01 10:45 3 5 pr ab pr           1
3: 17-12-01 11:15 2 4 ab pr pr           2
4: 17-12-01 11:40 2 4 ab pr pr           2
5: 17-12-01 11:15 6 7 ab pr ab           3
6: 17-12-01 11:45 3 4 pr ab pr           1

请注意,OP提供的样本数据集已被修改为包含第6行,该行与行1和2具有相同的Combination数字。

答案 2 :(得分:0)

以下是使用dplyr进行自己方法的相对简单的扩展:

tab %>%
  left_join(distinct(tab, A, B, C, .keep_all = TRUE) %>%
              mutate(unique = "1"), suffix = c(".x", ".y"))

合并完整和不同的数据框,用不同的标签

标记不同的数据框
#output:
      Date  Time X Y  A  B  C unique
1 17-12-01 10:15 2 4 pr ab pr      1
2 17-12-01 10:45 3 5 pr ab pr   <NA>
3 17-12-01 11:15 2 4 ab pr pr      1
4 17-12-01 11:40 2 4 ab pr pr   <NA>
5 17-12-01 11:15 6 7 ab pr ab      1

可以使用其他代码来替换NAs

.... %>%
replace_na(list(unique = 0))

其中tab是:

tab = read.table(text = "Date      Time    X    Y    A   B   C
17-12-01  10:15   2    4    pr  ab  pr
17-12-01  10:45   3    5    pr  ab  pr
17-12-01  11:15   2    4    ab  pr  pr
17-12-01  11:40   2    4    ab  pr  pr
17-12-01  11:15   6    7    ab  pr  ab", header = T)

这是一项绩效衡量标准:

library(microbenchmark)
microbenchmark(tab %>%
                 left_join(distinct(tab, A, B, C, .keep_all = TRUE) %>%
                             mutate(unique = "1"), suffix = c(".x", ".y")) %>%
                 replace_na(list(unique = 0)),
tab %>%
  group_by(A, B, C) %>% 
  mutate(id = row_number(),
         label = case_when(id >= 2 ~ "duplicate",
                           TRUE ~ "unique")))

#output with 100000 rows: `tab <- tab[sample(1:5, 100000, replace = T),]`

     min        lq     mean   median       uq      max neval
 12.099989 12.564350 13.43444 12.88050 13.44687 34.73189   100
  9.374461  9.928966 11.62848 10.33991 11.57404 49.86249   100

#output with 1 million rows:

      min       lq     mean   median        uq      max neval
 83.26594 85.65350 94.57422 86.24378 105.48224 254.9932   100
 68.81993 88.88253 92.75600 91.22021  93.06835 255.9896   100

如此相似的表现