目标是为数据框中的因子/字符串变量创建指标。该数据帧具有> 2毫米行,并在窗口上运行R,我没有选择使用plyr与.parallel = T。所以我正在与plyr和reshape2一起采取“分而治之”的路线。
运行融化和强制转换耗尽内存,并使用
ddply( idata.frame(items) , c("ID") , function(x){
( colSums( model.matrix( ~ x$element - 1) ) > 0 )
} , .progress="text" )
或
ddply( idata.frame(items) , c("ID") , function(x){
( elements %in% x$element )
} , .progress="text" )
确实需要一段时间。最快的方法是调用下面的tapply。你有没有办法加快速度? %in语句的运行速度比model.matrix调用快。感谢。
set.seed(123)
dd <- data.frame(
id = sample( 1:5, size=10 , replace=T ) ,
prd = letters[sample( 1:5, size=10 , replace=T )]
)
prds <- unique(dd$prd)
tapply( dd$prd , dd$id , function(x) prds %in% x )
答案 0 :(得分:4)
对于此问题,包bigmemory
和bigtabulate
可能是您的朋友。这是一个稍微雄心勃勃的例子:
library(bigmemory)
library(bigtabulate)
set.seed(123)
dd <- data.frame(
id = sample( 1:15, size=2e6 , replace=T ),
prd = letters[sample( 1:15, size=2e6 , replace=T )]
)
prds <- unique(dd$prd)
benchmark(
bigtable(dd,c(1,2))>0,
table(dd[,1],dd[,2])>0,
xtabs(~id+prd,data=dd)>0,
tapply( dd$prd , dd$id , function(x) prds %in% x )
)
基准测试的结果(我一直在学习新事物):
test replications elapsed relative user.self sys.self user.child sys.child
1 bigtable(dd, c(1, 2)) > 0 100 54.401 1.000000 51.759 3.817 0 0
2 table(dd[, 1], dd[, 2]) > 0 100 112.361 2.065422 107.526 6.614 0 0
4 tapply(dd$prd, dd$id, function(x) prds %in% x) 100 178.308 3.277660 166.544 13.275 0 0
3 xtabs(~id + prd, data = dd) > 0 100 229.435 4.217478 217.014 16.660 0 0
这表明bigtable
赢得了相当多的奖金。结果几乎所有pr都在所有ID中,但有关结果格式的详细信息,请参阅?bigtable
。
答案 1 :(得分:2)
你能再多说一下这个问题在级别数量,ID数量等方面的扩展程度吗?(如果保持级别数量固定,那么对于足够多的人来说,你正在计算的指标矩阵将会接近所有TRUE /全1 ...)?我预计xtabs
会更快,但不是这个尺寸的例子......
library(rbenchmark)
benchmark(
tapply( dd$prd , dd$id , function(x) prds %in% x ),
xtabs(~id+prd,data=dd)>0)
test replications elapsed relative
1 tapply(...) 100 0.053 1.000000
2 xtabs(...) > 0 100 0.120 2.264151
答案 2 :(得分:1)
您对%in%
功能的使用似乎是我的倒退。如果您想要每行数据的真/假结果,那么您应该使用%in%作为向量操作或ave
。虽然这里不需要它,但如果有一个更复杂的功能需要应用于每个项目,你可能想要使用它。
set.seed(123)
dd <- data.frame(
id = sample( 1:5, size=10 , replace=T ) ,
prd = letters[sample( 1:5, size=10 , replace=T )]
)
prds <- unique(dd$prd)
target.prds <- prds[1:2]
dd$prd.in.trgt <- with( dd, prd %in% target.prds)