Вы можете найти решение data.table
здесь. Если OP хочет только решение на основе R, я удалю этот пост:
library(data.table)
mtd_dt <- function() {
setDT(dtX)[, u := as.integer(gsub("row","",u))]
mX <- melt(dtX, id.var="u", variable.name="col")
C2 <- data.table(rn=seq_len(nrow(C)), u=as.integer(gsub("row","",rownames(C))))
dcast(mX[C2, on=.(u)][, sum(value), by=.(rn, col)], rn ~ col, value.var="V1")[,
"NA" := NULL][,
lapply(.SD, function(x) replace(x, is.na(x), 0))]
}
тайминги:
# A tibble: 2 x 14
expression min mean median max `itr/sec` mem_alloc n_gc n_itr total_time result memory time gc
<chr> <bch:tm> <bch:tm> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <bch:tm> <list> <list> <list> <list>
1 mtd0() 59.1s 59.1s 59.1s 59.1s 0.0169 447MB 24 1 59.1s <dbl [50 x 20,000]> <Rprofmem [44,515 x ~ <bch:t~ <tibble [1 x 3~
2 mtd_dt() 2.7s 2.7s 2.7s 2.7s 0.370 309MB 4 1 2.7s <data.table [50 x 20,001~ <Rprofmem [88,029 x ~ <bch:t~ <tibble [1 x 3~
временной код:
mtd0 <- function() {
for (i in 1:nrow(C)) {
indexes <- which(u==rownames(C)[i])
C[i, ] <- colSums(X[indexes, ])
}
C
}
bench::mark(mtd0(), mtd_dt(), check=FALSE)
данные:
library(data.table)
set.seed(0)
#d1 <- 10
#d2 <- 10
#d3 <- 5
d1<-400
d2<-20000
d3<-50
X <- as.data.frame(matrix(rnorm(d1*d2),nrow=d1,ncol=d2))
rownames(X) <- paste0("row",1:nrow(X))
colnames(X) <- paste0("col",1:ncol(X))
dtX <- X
u <- sample(rownames(X),nrow(X),replace=TRUE)
C <- matrix(0,nrow=d3,ncol=d2)
rownames(C) <- sample(rownames(X),nrow(C),replace=FALSE)