Подведите итог по столбцу эффективно - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть большая таблица, похожая на datadf с 3000 тысячами столбцов и строк, я видел несколько способов получения ожидаемого результата при переполнении стека ( Частота значений на столбец в таблице ), но дажесамый быстрый очень медленный для моего стола.РЕДАКТИРОВАТЬ: спасибо комментариям, несколько методов в настоящее время являются удовлетворительными.

library(data.table)
library(tidyverse)
library(microbenchmark)

datadf <- data.frame(var1 = rep(letters[1:3], each = 4), var2 = rep(letters[1:4], each = 3), var3 = rep('m', 12), stringsAsFactors = F )
datadf <- datadf[sample(1:nrow(datadf), 1000, T),sample(1:ncol(datadf), 1000, T)]
dataDT <- as.data.table(datadf)
lev<-unique(unlist(datadf))

microbenchmark(
 #base EDITED based on comment
 sapply(datadf, function(x) table(factor(x, levels=lev, ordered=TRUE))), #modified based on comment

 #tidyverse EDITED based on comment
 datadf %>% gather() %>% count(key, value) %>% spread(key, n, fill = 0L), # based on comment

 #data.table
  dcast(melt(dataDT, id=1:1000, measure=1:1000)[,1001:1002][, `:=` (Count = .N), by=.(variable,value)], value ~ variable ,
        value.var = "value", fun.aggregate = length),

 # EDITED, In Answer below
 dcast.data.table(
    melt.data.table(dataDT, measure.vars = colnames(dataDT))[, .N, .(variable, value)],
    value ~ variable,
    value.var = "N",
    fill = 0
  ),
  times=1
)

       min          lq        mean      median          uq         max  neva
   86.8522     86.8522     86.8522     86.8522     86.8522     86.8522     1
  207.6750    207.6750    207.6750    207.6750    207.6750    207.6750     1
12207.5694  12207.5694  12207.5694  12207.5694  12207.5694  12207.5694     1 
   46.3014     46.3014     46.3014     46.3014     46.3014     46.3014     1 # Answer      

1 Ответ

0 голосов
/ 11 сентября 2018

Это примерно вдвое быстрее, чем метод data.table, который вы предоставили, и должен очень хорошо масштабироваться с размером набора данных:

setDT(datadf)
dcast.data.table(
  melt.data.table(datadf, measure.vars = colnames(datadf))[, .N, .(variable, value)], 
  value ~ variable,
  value.var = "N",
  fill = 0
)

Мне было бы интересно увидеть тесты для вашегополный набор данных, потому что не все эти методы будут масштабироваться одинаково.

...