从类似id的不同行中排除重复值

时间:2018-04-30 21:58:29

标签: r data.table

我有一个数据集,其中不同的值位于一列中。我知道这不是一个好习惯,但这是我无法控制的。示例数据集如下:

library(data.table)
a1 <- data.table(v1 = "a", v2 = "12,13,12,12,10")
a2 <- data.table(v1 = "b", v2 = "10,10,11,12")
a3 <- data.table(v1 = "b", v2 = "10,10,13,14,12")
DT <- rbindlist(list(a1, a2, a3))

我想创建一个新列,其中只有两行中“b”的唯一值。我试过这个:

DT[, v5 := paste(unlist(lapply(v2, function(x) unique(unlist(strsplit(as.character(x), ",", fixed = TRUE))))), collapse = ","), by = v1]

但它只排除每行中的重复值。我得到的是:

   v1             v2                   v5
1:  a 12,13,12,12,10             12,13,10
2:  b    10,10,11,12 10,11,12,10,13,14,12
3:  b 10,10,13,14,12 10,11,12,10,13,14,12

我希望在行“b”的列“v5”中获得的值是10,11,12,13,14。

我非常感谢你提供解决问题的指导。

2 个答案:

答案 0 :(得分:2)

DT[DT[,toString(unique(scan(text = v2,sep = ","))),by=v1],on="v1"]
Read 5 items
Read 9 items
   v1             v2                 V1
1:  a 12,13,12,12,10         12, 13, 10
2:  b    10,10,11,12 10, 11, 12, 13, 14
3:  b 10,10,13,14,12 10, 11, 12, 13, 14

您可以加入quiet=T,以便不打印读取的项目数:

DT[DT[,toString(unique(scan(text = v2,sep = ",",quiet = T))),by=v1],on="v1"]
   v1             v2                 V1
1:  a 12,13,12,12,10         12, 13, 10
2:  b    10,10,11,12 10, 11, 12, 13, 14
3:  b 10,10,13,14,12 10, 11, 12, 13, 14

DT[DT[,toString(unique(unlist(strsplit(v2,",")))),by=v1],on="v1"]
   v1             v2                 V1
1:  a 12,13,12,12,10         12, 13, 10
2:  b    10,10,11,12 10, 11, 12, 13, 14
3:  b 10,10,13,14,12 10, 11, 12, 13, 14

使用pasteunlist

 DT[DT[,.(V5=paste(unique(unlist(strsplit(v2,","))),collapse=",")),by=v1],on="v1"]
   v1             v2             V5
1:  a 12,13,12,12,10       12,13,10
2:  b    10,10,11,12 10,11,12,13,14
3:  b 10,10,13,14,12 10,11,12,13,14

答案 1 :(得分:1)

你非常接近解决方案。在应用paste之前,您必须为小组汇总(collapse unique)。

您可以尝试按v1汇总为:

DT[, .(v5 = paste(unique(unlist(strsplit(paste(v2,collapse = ","),
                              split = ","))),collapse=",")), by = v1]
#    v1             v5
# 1:  a       12,13,10
# 2:  b 10,11,12,13,14