R data.table生成每列的唯一值

时间:2018-04-30 23:54:23

标签: r data.table unique

我有一个data.table,我需要生成另一个data.table,它只列出每列的唯一值。一个例子:

> sourceDT <- data.table(ID = c(1,2,3,4), date = c(ymd("20110101"),ymd("20110101"),ymd("20130101"),ymd("20150101")), text = c("A","B","C","C"))
> sourceDT
   ID       date text
1:  1 2011-01-01    A
2:  2 2011-01-01    B
3:  3 2013-01-01    C
4:  4 2015-01-01    C

> outputDT <- data.table(ID = c(1,2,3,4),date = c(ymd("20110101"),ymd("20130101"),ymd("20150101"),NA), text = c("A","B","C",NA))
> outputDT
   ID       date text
1:  1 2011-01-01    A
2:  2 2013-01-01    B
3:  3 2015-01-01    C
4:  4       <NA>   NA

实现这一目标的最有效方法是什么?

2 个答案:

答案 0 :(得分:2)

你可以做的一种方式:(虽然我觉得效率不高:)

sourceDT[,lapply(.SD, function(x)sort(`is.na<-`(x,duplicated(x)),na.last = T))]
   ID       date text
1:  1 2011-01-01    A
2:  2 2013-01-01    B
3:  3 2015-01-01    C
4:  4       <NA>   NA

答案 1 :(得分:1)

这就是我对您的问题的理解,您所拥有的演示并不符合您对我的评论所说的内容。

这会在每列中找到重复项并将其设置为NA,这会保留data.table大小。

library(data.table)
library(lubridate)
sourceDT <- data.table(ID = c(1,2,3,4), date = c(ymd("20110101"),ymd("20110101"),ymd("20130101"),ymd("20150101")), text = c("A","B","C","C"))


for (i in seq_along(sourceDT)) {
  dupes <- which(duplicated(sourceDT[[i]]))
  if (length(dupes > 0)) {
    set(sourceDT, dupes, i, NA)
  }
}

#    ID       date text
# 1:  1 2011-01-01    A
# 2:  2       <NA>    B
# 3:  3 2013-01-01    C
# 4:  4 2015-01-01   NA