过滤重复的行序列

时间:2019-02-26 10:17:50

标签: r data.table

(请注意,我很惊讶没有找到类似的问题,但是如果我弄错了,我很乐意删除此问题)。

我有以下示例数据集。

library(data.table)
dt <- data.table(val = c(1, 2, 3, 0, 2, 4, 1, 2, 3), id = c(1, 1, 1, 2, 2, 2, 3, 3, 3))

id = 1的组的val(1,2,3)值与id = 3的组相同。我想过滤掉组id = 3中的“重复”值。

我想要的输出是:

> dt
   val id
1:   1  1
2:   2  1
3:   3  1
4:   0  2
5:   2  2
6:   4  2

我只想出了一些肮脏的解决方法,例如求和:dt[, filter:= sum(val) , by = id]并删除重复项,但是id = 2的值也将消失。

注意:如果id = 3的值应为1,3,2(因此,相同的值但顺序不同,则不应删除行),..所以顺序很重要。

3 个答案:

答案 0 :(得分:3)

这不是特定于data.table的方法,但可以使用:

x = split(dt$val, dt$id)
dt[!id %in% names(x[duplicated(x)])]
#   val id
#1:   1  1
#2:   2  1
#3:   3  1
#4:   0  2
#5:   2  2
#6:   4  2

就效率而言,这可能不是最佳选择。

答案 1 :(得分:2)

您可以转换为字符串,删除重复项并合并,即

merge(dt, unique(dt[, .(new = toString(val)), id], by = 'new'))[,new := NULL][]
#   id val
#1:  1   1
#2:  1   2
#3:  1   3
#4:  2   0
#5:  2   2
#6:  2   4

我们可以通过拉merge并使用id来避免%in%,即

i1 <- unique(dt[, .(new = toString(val)), id], by = 'new')[, id]
dt[id %in% i1,]
#   val id
#1:   1  1
#2:   2  1
#3:   3  1
#4:   0  2
#5:   2  2
#6:   4  2

答案 2 :(得分:1)

带有data.table的另一个选项:

dt <- dt[, pat := paste(val, collapse = "/"), by = id][
  , .SD[which.min(rleid(pat))], by = .(pat, val)][, pat := NULL]

输出:

   val id
1:   1  1
2:   2  1
3:   3  1
4:   0  2
5:   2  2
6:   4  2