R data.table高效重复计数

R data.table高效重复计数,r,performance,data.table,R,Performance,Data.table,使用data.table,我可以使用unique(mydt)来告诉我哪些行是唯一的行。我很想知道一行被复制了多少次。比如说 require(data.table) data.table(x = c('a', 'a', 'a', 'b', 'b'), y = c(1, 1, 2, 3, 4)) 应该找出唯一的行是 x y 1: a 1 2: a 2 3: b 3 4: b 4 而且行(a,1)有两个重复的行。到目前为止,我已经想出了 mydt.colnames =

使用data.table,我可以使用unique(mydt)来告诉我哪些行是唯一的行。我很想知道一行被复制了多少次。比如说

require(data.table)

data.table(x = c('a', 'a', 'a', 'b', 'b'),
           y = c(1, 1, 2, 3, 4))
应该找出唯一的行是

   x y
1: a 1
2: a 2
3: b 3
4: b 4
而且行(a,1)有两个重复的行。到目前为止,我已经想出了

mydt.colnames = colnames(mydt)
mydt.fweighted = mydt[,
                      list(fweight = .N),
                      by = mydt.colnames]
但这似乎非常缓慢,而且根本没有使用独特的功能。有没有一种快速的方法可以用unique实现这一点?

试试这个:

require(data.table)
data.table(x = c('a', 'a', 'a', 'b', 'b'),
           y = c(1, 1, 2, 3, 4))

sapply(1:nrow(unique(Table[,1])), function(x) 
length(which(Table[,1] == as.character(unique(Table[,1])[x]))))
就你的例子而言,这对我很有效

试试这个:

require(data.table)
data.table(x = c('a', 'a', 'a', 'b', 'b'),
           y = c(1, 1, 2, 3, 4))

sapply(1:nrow(unique(Table[,1])), function(x) 
length(which(Table[,1] == as.character(unique(Table[,1])[x]))))

对于您的示例,这对我在更大的数据集上进行测试非常有效:

n <- 2e6
set.seed(1)
mydt <- data.table(x = sample(LETTERS, n, replace = T),
                   y = sample(1:10, n, replace = T))


JCWong <- function(mydt) {
  mydt.colnames <- colnames(mydt)
  mydt.fweighted <- mydt[, list(N = .N), by = mydt.colnames]
  mydt.fweighted
}

thelatemail <- function(mydt) {
  mydt.fweighted2 <- mydt[unique(mydt), on = colnames(mydt), .N, by = .EACHI]
  mydt.fweighted2
}

all.equal(JCWong(mydt),  thelatemail(mydt))
# [1] TRUE

require(microbenchmark)
microbenchmark(JCWong(mydt),  thelatemail(mydt))
# Unit: milliseconds
#              expr      min       lq     mean   median       uq       max neval cld
#      JCWong(mydt) 32.80524 33.49849 35.22232 34.11636 35.70609  47.31256   100  a 
# thelatemail(mydt) 56.55455 57.38479 61.51967 58.05206 59.51973 124.02087   100   b

n在较大数据集上测试:

n <- 2e6
set.seed(1)
mydt <- data.table(x = sample(LETTERS, n, replace = T),
                   y = sample(1:10, n, replace = T))


JCWong <- function(mydt) {
  mydt.colnames <- colnames(mydt)
  mydt.fweighted <- mydt[, list(N = .N), by = mydt.colnames]
  mydt.fweighted
}

thelatemail <- function(mydt) {
  mydt.fweighted2 <- mydt[unique(mydt), on = colnames(mydt), .N, by = .EACHI]
  mydt.fweighted2
}

all.equal(JCWong(mydt),  thelatemail(mydt))
# [1] TRUE

require(microbenchmark)
microbenchmark(JCWong(mydt),  thelatemail(mydt))
# Unit: milliseconds
#              expr      min       lq     mean   median       uq       max neval cld
#      JCWong(mydt) 32.80524 33.49849 35.22232 34.11636 35.70609  47.31256   100  a 
# thelatemail(mydt) 56.55455 57.38479 61.51967 58.05206 59.51973 124.02087   100   b

n数据表需要它吗?或者data.frame可以工作?您的数据的维度是什么?这是“非常慢的”?我刚刚尝试了4M行,30个变量,它在不到2秒内完成。是
mydt[unique(mydt),on=colnames(mydt),.N,by=.EACHI]
对您来说更快了吗?这里似乎剃掉了一小部分。是的,这可能是最快的方法。也许你需要升级
.N
从1.9.8开始优化。。。数据表需要它吗?或者data.frame可以工作?您的数据的维度是什么?这是“非常慢的”?我刚刚尝试了4M行,30个变量,它在不到2秒内完成。是
mydt[unique(mydt),on=colnames(mydt),.N,by=.EACHI]
对您来说更快了吗?这里似乎剃掉了一小部分。是的,这可能是最快的方法。也许你需要升级
.N
从1.9.8开始优化。。。