data.table 标记列中没有重复值的行

data.table tag rows that have no duplicate values within a column

我有一个 data.table 如下所示

d_in_small <- data.table( score = c(94.272159,94.751695,106.588274,109.361865,111.017053,113.703024,118.638858,124.007419,125.695266,125.696385,94.272191,94.751649,95.496644,108.902001,113.703027),
                        group = c('a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'))
id score group
1 94.2721 a
2 94.7516 a
3 106.5882 a
4 109.3618 a
5 111.0170 a
6 113.7030 a
7 118.6388 a
8 124.0074 a
9 125.6952 a
10 125.6963 a
11 94.2721 a
12 94.7516 a
13 95.4966 a
14 108.9020 a
15 113.7030 a

我想确定哪些分数在数据集中只出现一次。例如第 1 行中的分数也在第 11 行中,但第 3 行中的分数是唯一的。

那么,有没有什么方法可以轻松识别 data.table 中的非重复项目并将它们添加到新列中以获得如下所示的输出?

id score group tag
1 94.2721 a
2 94.7516 a
3 106.5882 a outlier
4 109.3618 a outlier
5 111.0170 a outlier
6 113.7030 a
7 118.6388 a outlier
8 124.0074 a outlier
9 125.6952 a outlier
10 125.6963 a outlier
11 94.2721 a
12 94.7516 a
13 95.4966 a outlier
14 108.9020 a outlier
15 113.7030 a

这里的DT snap是一个示例,所以在整个数据集上应用时,它们将按group列分组。

谢谢

尝试:

d_in_small[,outlier:=if (.N==1) 'outlier',by=score]

请注意,由于最后一位小数,您提供的示例数据集只有异常值。 您可以按 round(score,decimals) 分组以获得您想要检测异常值的精度。

例如:

d_in_small[,outlier:=if (.N==1) 'outlier',by=round(score,4)][]
        score  group outlier
        <num> <char>  <char>
 1:  94.27216      a    <NA>
 2:  94.75169      a outlier
 3: 106.58827      a outlier
 4: 109.36186      a outlier
 5: 111.01705      a outlier
 6: 113.70302      a    <NA>
 7: 118.63886      a outlier
 8: 124.00742      a outlier
 9: 125.69527      a outlier
10: 125.69639      a outlier
11:  94.27216      a    <NA>
12:  94.75165      a outlier
13:  95.49664      a outlier
14: 108.90200      a outlier
15: 113.70303      a    <NA>

先标记重复项,然后将 FALSE 值更改为 outlier 可能是一种处理方法

d_in_small[, tag := .N > 1, by = score]
d_in_small$tag <- ifelse(d_in_small$tag=='FALSE','outlier','TRUE')

这是一个选项。我定义了一个舍入函数,使代码更具可读性。

f <- function(x) round(x, 4)

d_in_small[, tag := duplicated(f(score)) | duplicated(f(score), fromLast = TRUE)]
d_in_small[, tag := c("outlier", "")[tag + 1L]]
d_in_small