5

目标是为数据框中的因子/字符串变量创建指标。该数据框的行数 > 2mm,并且在 Windows 上运行 R,我没有选择将 plyr 与 .parallel=T 一起使用。所以我用 plyr 和 reshape2 走“分而治之”的路线。

运行 melt 和 cast 耗尽内存,并使用

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 )
4

3 回答 3

4

对于这个问题,包bigmemorybigtabulate可能是你的朋友。这是一个更雄心勃勃的例子:

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赢得了可观的金额。结果几乎是所有prds都在所有ID中,但?bigtable有关结果格式的详细信息,请参阅。

于 2012-03-26T20:50:44.960 回答
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  
于 2012-03-26T19:57:32.950 回答
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)
于 2012-03-26T19:50:58.690 回答