2017-06-12 53 views
-2

我使用这段代码。但它非常耗时。我怎么能加快这一点。有任何帮助吗?我该如何加快我的代码(矩阵,sapply,lapply)

veri=replicate(1000, sim.VSS(ncases=3000, nvariables=20, nfactors=1, meanloading=0.5,dichot=1,cut=0)) 
#save date set 
for (i in 1:1000){ 
    write.csv(veri[,,i], paste("v_30002005d_", i, ".csv", sep="")) 
} 

#read csvs 
files<- lapply(1:1000, function(x) { read.csv(paste0("v_30002005d_", x, ".csv"))}[,2:21]) 

formula<- function(a){ 
    sapply(1:nrow(a), function(x) sapply(1:ncol(a), 
             function (y) {{ifelse((as.matrix(rowMeans(a)))[x,]+as.matrix(colMeans(a))[y]>=1 , a[x,y]+as.matrix(item.exam(a)$Item.Rel.woi)[y,],a[x,y])}}) 
)} 

new_mat=sapply(1:1000, function(z){t(formula(files[[z]]))}) 
+2

什么部分是慢的?你有没有尝试分析代码找到瓶颈?通过并行运行代码可以改进读/写。 –

+1

在写第三点之前,我想问一下:你是否需要为rowMeans和colMeans设置矩阵对象?它们被创建为一维矢量对象,除非将它们转换为矩阵,并且子集化矩阵比子集矢量效率低得多。 –

+0

@RomanLuštrik,读/写并行打击I/O瓶颈的可能性有多大? –

回答

1

两点:

  • 的rowMeans部分(a)重新计算在内部sapply每次迭代(1:NcoI位(a))和也sapply(1:nrow的(a))。对于colMeans(a)部分也是如此。对于尺寸为n和m的O(m * n^2)时间过长的大对象(因此对于方形对象,执行时间随着维度的立方体增加)。您可以在“公式”函数的开始处计算行和列的平均值,并将这些值分配给对象,而不是在闭合内填充everthing。一个更简洁的方法是单独定义最内层功能并对其进行函数调用(可能会因通话而导致一些惩罚,但会使代码更加优雅和可跟踪)

  • 而不是两个sapply的行和列使用外层,它是层片的二维版本。然而为了这个工作,里面的函数必须是矢量化的。你可以定义一个矢量化版本的函数x y向量化(x)

+0

我不确定第二点会有多好。但第一个是绝对值得的。 –

+0

我纠正了我的观点,因为情况更糟糕:有两个嵌套层,所以大O是立方体而不是方形。 –