我正在使用以下脚本分析大量数据:
M <- c_alignment
c_check <- function(x){
if (x == c_1) {
1
}else{
0
}
}
both_c_check <- function(x){
if (x[res_1] == c_1 && x[res_2] == c_1) {
1
}else{
0
}
}
variance_function <- function(x,y){
sqrt(x*(1-x))*sqrt(y*(1-y))
}
frames_total <- nrow(M)
cols <- ncol(M)
c_vector <- apply(M, 2, max)
freq_vector <- matrix(nrow = sum(c_vector))
co_freq_matrix <- matrix(nrow = sum(c_vector), ncol = sum(c_vector))
insertion <- 0
res_1_insertion <- 0
for (res_1 in 1:cols){
for (c_1 in 1:conf_vector[res_1]){
res_1_insertion <- res_1_insertion + 1
insertion <- insertion + 1
res_1_subset <- sapply(M[,res_1], c_check)
freq_vector[insertion] <- sum(res_1_subset)/frames_total
res_2_insertion <- 0
for (res_2 in 1:cols){
if (is.na(co_freq_matrix[res_1_insertion, res_2_insertion + 1])){
for (c_2 in 1:max(c_vector[res_2])){
res_2_insertion <- res_2_insertion + 1
both_res_subset <- apply(M, 1, both_c_check)
co_freq_matrix[res_1_insertion, res_2_insertion] <- sum(both_res_subset)/frames_total
co_freq_matrix[res_2_insertion, res_1_insertion] <- sum(both_res_subset)/frames_total
}
}
}
}
}
covariance_matrix <- (co_freq_matrix - crossprod(t(freq_vector)))
variance_matrix <- matrix(outer(freq_vector, freq_vector, variance_function), ncol = length(freq_vector))
correlation_coefficient_matrix <- covariance_matrix/variance_matrix
Run Code Online (Sandbox Code Playgroud)
模型输入将是这样的:
1 2 1 4 3
1 3 4 2 1
2 3 3 3 1
1 1 2 1 2
2 3 4 4 2
Run Code Online (Sandbox Code Playgroud)
我正在计算是每个国家的二项式方差发现M[,i],在发现的每个状态M[,j].每行都是为该试验找到的状态,我想看看列的状态如何共同变化.
澄清:我找到了两个多项分布的协方差,但我是通过二项式比较来做到的.
输入是4200 x 510矩阵,每列的c值平均约为15.我知道forR中的循环速度非常慢,但我不确定如何在apply这里使用该函数.如果有人建议apply在这里正确使用,我真的很感激.现在脚本需要几个小时.谢谢!
Jor*_*eys 15
我想写评论,但我有太多话要说.
首先,如果你认为申请更快,那么看看R的申请家庭比语法糖更多吗?.它可能是,但它远没有保证.
接下来,请不要在浏览代码时增加矩阵,这会令您的代码变得非常糟糕.预分配矩阵并将其填满,这可以将代码速度提高十倍以上.你通过你的代码生长不同的向量和矩阵,这是疯了(请原谅我强烈的演讲)
然后,查看帮助页面?subset和那里给出的警告:
这是一种便于交互使用的便利功能.对于编程,最好使用像[的标准子集函数,特别是参数子集的非标准评估可能会产生意想不到的后果.
总是.使用.指数.
此外,您一遍又一遍地重新计算相同的值.fre_res_2例如,为每个res_2和state_2计算的次数与你res_1和的组合一样多state_1.这只是浪费资源.退出循环,不需要重新计算,并将其保存在可以再次访问的矩阵中.
哎呀,现在我就是它:请使用矢量化函数.再想一想,看看你可以拖出循环:我认为这是你计算的核心:
cov <- (freq_both - (freq_res_1)*(freq_res_2)) /
(sqrt(freq_res_1*(1-freq_res_1))*sqrt(freq_res_2*(1-freq_res_2)))
Run Code Online (Sandbox Code Playgroud)
在我看来,你可以构造一个矩阵freq_both,freq_res_1和freq_res_2,并将它们用作那一行的输入.这将是整个协方差矩阵(不称之为cov,cov是一个功能).退出循环.输入快速代码.
鉴于我不知道c_alignment中有什么,我不会为你重写你的代码,但你绝对应该摆脱C思维方式并开始思考R.
让这成为一个开始:R Inferno
这并不是真正的 4 路嵌套循环,而是代码在每次迭代中增加内存的方式。在我放置 和 行的地方,这种情况发生了# **4cbind次rbind。在这种情况下,R(以及 Matlab 和 Python)中的标准建议是提前分配,然后填充。这就是函数的作用apply。他们分配list已知数量的结果,将每个结果分配给每个槽,然后在最后将所有结果合并在一起。在你的情况下,你可以提前分配正确的大小矩阵,并在这 4 个点上分配给它(粗略地说)。这应该和apply家庭一样快,而且您可能会发现编码更容易。