2014-11-11 2 views
0

Я пытаюсь отфильтровать низкочастотные факторы в наборе данных. Проблема выглядит примерно так:Каков самый быстрый способ получить частоту фактора в R?

require(digest) 
require(ff) 
require(ffbase) 

test.vector.ffdf = as.ffdf(as.ff(as.factor(sample(sapply(1:1000, digest), 50000000, replace = T)))) 

get.frequency=function(i,column){ 
    freq = sum(test.vector.ffdf[,column] == i)/length(test.vector.ffdf[,column]) 
    print(paste0(i,' ',freq)) 
    freq 
} 

column = 1 
sapply(unique(test.vector.ffdf[,column]),get.frequency, column = column) 

Как вы можете видеть, это занимает очень много времени, и у меня есть несколько столбцов, чтобы сделать это с тысячами факторов. Есть ли способ получить частоты намного быстрее?

Разъяснение: в этом примере, печать() в функции только видеть прогресс и sapply будет использоваться, чтобы получить список частот, которые можно было бы действовал на то [я где частота < 0,001]

+2

Я думаю, что вы ищете 'table()'. – eipi10

+0

Я бы попробовал таблицу (as.data.frame (test.vector.ffdf)) – user3969377

+0

Спасибо, ребята. Я разместил его в форме ответа, так как он работал хорошо. @ user3969377, пакет ('ffbase') перегружает таблицу для работы с ffdfs. Я действительно пытался избежать конвертирования в фрейм данных, так как это делает все в памяти, что абсолютно огромно. –

ответ

1
require(digest) 
require(ff) 
require(ffbase) 

test.vector.ffdf = as.ffdf(as.ff(as.factor(sample(sapply(1:10, digest), 50000000, replace = T)))) 
test.vector.ffdf$one <- ff(1L, length = nrow(test.vector.ffdf)) 
system.time(binned_sum(x = test.vector.ffdf$one, bin = test.vector.ffdf$x)) 
# user system elapsed 
# 1.463 0.372 1.835 
0

Я пытался несколько различных методов из What is the fastest way to obtain frequencies of integers in a vector?, которые, конечно, являются Интс, а не персонажи -

require(digest) 
require(ff) 
require(ffbase) 

test.vector.ffdf = as.ffdf(as.ff(as.factor(sample(sapply(1:10, digest), 50000000, replace = T)))) 

get.frequency=function(i,column){ 
    freq = sum(test.vector.ffdf[,column] == i)/length(test.vector.ffdf[,column]) 
    #print(paste0(i,' ',freq)) 
    freq 
} 

column = 1 

x = test.vector.ffdf[,column] 

system.time(table(x)) 
# user system elapsed 
# 3.548 0.000 3.561 

system.time(sapply(unique(test.vector.ffdf[,column]),get.frequency, column = column)) 
# user system elapsed 
# 39.049 5.127 44.322 

system.time({cdf<-cbind(sort(x),seq_along(x)); cdf<-cdf[!duplicated(cdf[,1]),2]; c(cdf[-1],length(x)+1)-cdf}) 
# user system elapsed 
#217.060 2.851 220.865 

редактировать: добавление раствора выше, так что можно сравнить с той же самой системе:

test.vector.ffdf$one <- ff(1L, length = nrow(test.vector.ffdf)) 
> system.time(binned_sum(x = test.vector.ffdf$one, bin = test.vector.ffdf$x)) 
# user system elapsed 
# 0.731 0.283 1.018 

Итак, похоже, что таблица является явным победителем и не зависит от количества факторов, таких как мое решение.

+0

Фактор - это int, с соответствующей меткой. – mnel