Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 统计每个data.table行的出现次数_R_Data.table - Fatal编程技术网

R 统计每个data.table行的出现次数

R 统计每个data.table行的出现次数,r,data.table,R,Data.table,我有一个data.table太大,无法在RAM中熔化/铸造(数百万行) 从中,我需要提取每行没有重复值的行。重复的零和NA可以保留 在这个MWE中,“Duplicates”-列是我想要计算的 DT <- data.table(C1=c(0L, 7L, 0L, 0L), C2=c(0L, 0L, 0L, 4L), C3=c(2L, 0L, 2L, 3L), C4=c(0L, NA_integ

我有一个data.table太大,无法在RAM中熔化/铸造(数百万行)

从中,我需要提取每行没有重复值的行。重复的零和NA可以保留

在这个MWE中,“Duplicates”-列是我想要计算的

DT <- data.table(C1=c(0L, 7L, 0L, 0L),
                 C2=c(0L, 0L, 0L, 4L),
                 C3=c(2L, 0L, 2L, 3L),
                 C4=c(0L, NA_integer_, 2L, 6L),
                 C5=c(1L, 3L, 1L, 1L),
                 c6=c(0L, 4L, 2L, 4L),
                 Duplicates=c(FALSE, FALSE, TRUE, TRUE))

DT.wanted <- DT[Duplicates==FALSE, ]

DT这里有一个解决方案,应该还是稍微快一点(~3x)


foo_dup这里是另一个数据。表开始处理事情

DT[ lapply( data.table::transpose( DT ), 
            function(x) anyDuplicated( x[!is.na(x) & !x == 0] ) ) == 0, ]
不知道它如何保持记忆。。但是WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

基准

# Unit: microseconds
#      expr     min         lq      mean    median         uq       max neval
#      loop 11764.5 12164.2010 13987.589 12725.601 13775.0010 25885.601   100
# transpose   524.5   550.3515   592.633   566.601   597.4515  1116.201   100
基准代码

mydata <- data.table(C1=c(0L, 7L, 0L, 0L),
                 C2=c(0L, 0L, 0L, 4L),
                 C3=c(2L, 0L, 2L, 3L),
                 C4=c(0L, NA_integer_, 2L, 6L),
                 C5=c(1L, 3L, 1L, 1L),
                 C6=c(0L, 4L, 2L, 4L))

microbenchmark::microbenchmark(
 loop = {
   DT <- copy(mydata)   
   DT[, Duplicates:=FALSE]
   for (i in 1L:nrow(DT)){
     dt.i <- data.table(table(as.integer(DT[i, ])))
     if (max(dt.i[V1>0, N])>1) DT[i, Duplicates:=TRUE]
   }
 },
 transpose = {
   DT <- copy(mydata)
   DT[ lapply( transpose(DT), function(x) anyDuplicated( x[!is.na(x) & ! x == 0] ) ) == 0, ]
 },times = 100L )

mydata这里是另一种使用基本R+
数据的方法。table::rowidv
(大约是1mio数据行所选解决方案的8倍):

具有1e6行数据的计时:

mSD <- as.matrix(DT)
mSD[mSD==0L] <- NA_integer_
m <- cbind.data.frame(ROW=rep(1L:nrow(mSD), ncol(mSD)), COL=as.vector(mSD))
mcc <- m[complete.cases(m),]
dup <- unique(mcc$ROW[rowidv(mcc) > 1L])
DT[-dup]
Unit: seconds
      expr      min       lq     mean   median       uq      max neval
 mtd0(DT0) 9.902526 9.902526 9.902526 9.902526 9.902526 9.902526     1
 mtd2(DT2) 1.234894 1.234894 1.234894 1.234894 1.234894 1.234894     1

我必须使用
data.table
或者我可以使用其他pkg/base R吗?据我所知,只有data.table可以在不重写表的情况下执行此操作。没有足够的内存。这肯定会导致内存问题,但你可以结合这个独奏和我的循环。可能将data.table拆分为10个部分,并逐步应用此解决方案。是的,仍然需要大量内存。感谢您提供拆分data.table的提示
mSD <- as.matrix(DT)
mSD[mSD==0L] <- NA_integer_
m <- cbind.data.frame(ROW=rep(1L:nrow(mSD), ncol(mSD)), COL=as.vector(mSD))
mcc <- m[complete.cases(m),]
dup <- unique(mcc$ROW[rowidv(mcc) > 1L])
DT[-dup]
library(data.table)
set.seed(0L)
nr <- 1e5L
nc <- 6L
dat <- as.data.table(matrix(sample(c(0L:7L, NA_integer_), nr*nc, TRUE), nrow=nr))
DT0 <- copy(dat)
DT1 <- copy(dat)
DT2 <- copy(dat)

mtd0 <- function(DT) {
    DT[ lapply(transpose(DT),
        function(x) anyDuplicated( x[!is.na(x) & !x == 0] ) ) == 0, ]
}

mtd1 <- function(DT) {
    foo_dup <- function(x) {
        anyDuplicated(x[!is.na(x) & x != 0L]) != 0L
    }

    cols <- copy(names(DT))
    for (i in 1L:nrow(DT)) {
        set(DT, i, "Duplicates", foo_dup(unlist(DT[i, ..cols])) )
    }
}

mtd2 <- function(DT) {

    mSD <- as.matrix(DT)
    mSD[mSD==0L] <- NA_integer_
    m <- cbind.data.frame(ROW=rep(1L:nrow(mSD), ncol(mSD)), COL=as.vector(mSD))
    mcc <- m[complete.cases(m),]
    dup <- unique(mcc$ROW[rowidv(mcc) > 1L])

    DT[-dup]
}

microbenchmark::microbenchmark(times=1L, mtd0(DT0), mtd1(DT1), mtd2(DT2))
Unit: milliseconds
      expr          min           lq         mean       median           uq          max neval
 mtd0(DT0)    999.47159    999.47159    999.47159    999.47159    999.47159    999.47159     1
 mtd1(DT1) 110725.50423 110725.50423 110725.50423 110725.50423 110725.50423 110725.50423     1
 mtd2(DT2)     64.79497     64.79497     64.79497     64.79497     64.79497     64.79497     1
Unit: seconds
      expr      min       lq     mean   median       uq      max neval
 mtd0(DT0) 9.902526 9.902526 9.902526 9.902526 9.902526 9.902526     1
 mtd2(DT2) 1.234894 1.234894 1.234894 1.234894 1.234894 1.234894     1