在数据表中的行中计算nr个重复记录

时间:2018-04-06 22:21:26

标签: r data.table

我想确定大数据表中某些列的每行重复记录的数量。具有所需输出的简单示例:

test <- data.table(a=c(1,2,3),b=c(1,4,6),c=c(5,6,9),duplicatercds=c(1,0,0))

这是否有命令?

4 个答案:

答案 0 :(得分:2)

在计算欺骗之前,您可以融入长格式

library(data.table)
DT <- data.table(a=c(1,2,3),b=c(1,4,6),c=c(5,6,9))

stat <- melt(DT[, rn:=.I], id.vars="rn")[, 
    .(duplicatercds=.N - uniqueN(value)), by=.(rn)]
DT[stat, duplicatercds := duplicatercds, on=.(rn)]        

由于机器精度

,在双值上执行uniqueN时要小心

有一个github fr:https://github.com/Rdatatable/data.table/issues/1063

编辑: 另一种清洁方法

DT[, duplicatercds := apply(.SD, 1, function(x) length(x) - uniqueN(x))]

编辑:添加了一些时间:

library(data.table)
set.seed(0L)
ncols <- 10L
nrows <- 1e4L
uniqVal <- seq_len(1000L)
test <- as.data.table(matrix(sample(uniqVal, nrows*ncols, replace=TRUE), nrow=nrows))
test[, duplicatercds := NA_real_]

f1 <- function() test[, apply(.SD, 1, function(x) { y <- table(x); sum(y) - length(y) }) ]
f2 <- function() test[, sum(table(unlist(.SD)) > 1), by=.(1:nrows)]$V1
f3 <- function() test[, apply(test, 1, function(x) sum(diff(sort(x))==0))]
f4 <- function() test[, apply(.SD, 1, function(x) length(x) - uniqueN(x))]
f5 <- function() test[, ncols - vapply(transpose(.SD), uniqueN, 1L) + 1L]

identical(f2(), f1())
# [1] FALSE

identical(f3(), f1())
# [1] TRUE

identical(f4(), f1())
# [1] TRUE

identical(unname(f5()), f1())
# [1] TRUE


library(microbenchmark)
microbenchmark(f1(), f2(), f3(), f4(), f5(), times=5L)

# Unit: milliseconds
#  expr       min        lq      mean    median        uq       max neval
#  f1() 1883.7817 1903.7626 1940.5378 1922.6539 1981.1139 2011.3771     5
#  f2() 1821.0437 1901.1188 1933.8926 1908.4297 1999.6216 2039.2491     5
#  f3()  657.4502  666.6721  679.5539  672.6617  686.4095  714.5760     5
#  f4()  167.8048  168.5211  174.3660  169.9920  180.1304  185.3816     5
#  f5()  146.0255  154.6341  159.4630  160.1968  164.3369  172.1219     5

答案 1 :(得分:2)

假设您没有最后一栏,那么您可以通过以下方式获得所需的结果(以澄清您的澄清评论为模):

test[ ,duplicatercds := apply(.SD, 1, function(x) {sum(table(x))-length(table(x))}), 
                          by=1:nrow(test) ]
> test
   a b c duplicatercds
1: 1 1 5             1
2: 2 4 6             0
3: 3 6 9             0

&#39;测试&#39;有一个更复杂的例子:

> test <- data.table(a=c(1,2,3),b=c(1,4,6),c=c(5,6,9), d=c(1,2,3), c=c(5,6,9))
> test
   a b c d c
1: 1 1 5 1 5
2: 2 4 6 2 6
3: 3 6 9 3 9
> test[ , duplicatercds := apply(.SD, 1, function(x) {sum(table(x))-length(table(x))}), by=1:nrow(test) ]
> test
   a b c d c duplicatercds
1: 1 1 5 1 5             3
2: 2 4 6 2 6             2
3: 3 6 9 3 9             2

或者也许:

test[ , duplicatercds := apply(.SD, 1,
                                    function(x) {sum(table(x))-length(table(x))}) ]

答案 2 :(得分:0)

一种解决方案是使用diff作为apply函数的一部分。

test <- data.table(a=c(1,2,3),b=c(1,4,6),c=c(5,6,9))
test$dup <- apply(test,1,function(x)sum(diff(sort(x))==0))
test
#    a b c dup
# 1: 1 1 5   1
# 2: 2 4 6   0
# 3: 3 6 9   0

答案 3 :(得分:0)

你可以做一张桌子,并计算有多少人的频率超过1

test=test[,1:3]#Remove your duplicatercds
test[, duplicatercds:=sum(table(unlist(.SD))>1),by=.(1:nrow(test))][]

   a b c duplicatercds 
1: 1 1 5             1           
2: 2 4 6             0          
3: 3 6 9             0