ユーザー定義関数で行列の各要素を計算しようとしています。二重for
ループ、ネストされたsapply
、およびapply
afterを使用しましたexpand.grid
。
# create dataset
ll = lapply(1:20, FUN = function(x) floor(runif(n=floor(runif(1,10,30)),1,50)))
# sapply line
doSapply = function(ll){
m = sapply(1:length(ll),FUN = function(x){sapply(1:length(ll),FUN = function(y){if(length(intersect(ll[[x]],ll[[y]]))>1){return(1)}else{return(0)}})})
}
doFor = function(ll){
m = matrix(rep(0,length(ll)*length(ll)),length(ll))
# double for loop
for(x in 1:length(ll)){
for(y in 1:length(ll)){
if(length(intersect(ll[[x]],ll[[y]]))>1){
m[x,y] = 1
} else{
m[x,y] = 0
}
}
}
}
doApply = function(ll){
x = expand.grid(1:length(ll),1:length(ll))
vals = apply(x,1,FUN = function(x){
if(length(intersect(ll[[x[1]]],ll[[x[2]]]))>1){
return(1)
} else{
return(0)
}
} )
matrix(vals,nrow=length(ll),byrow=FALSE)
# return(matrix(vals,nrow=length(ll),byrow=FALSE))
}
timeSapply = system.time(doSapply(ll))
timeFor = system.time(doFor(ll))
timeApply = system.time(doApply(ll))
私はより洗練されたソリューションを探しています (もちろん、より高速です)。私はアウターを使おうとしています、そして私は書きました:
doOuter = function(ll){
outer(1:length(ll),1:length(ll),FUN = function(x,y){if(length(intersect(ll[[x]],ll[[y]]))>1){return(1)}else{return(0)}})
}
私は得たError in ll[[y]] : recursive indexing failed at level 2
Outer は関数をベクトル化する必要があると考えたので、試してみました。
doMatch = function(x,y,ll){
if(length(intersect(ll[[x]],ll[[y]]))>1){return(1)}else{return(0)}
}
doMatVec = Vectorize(doMatch)
outer(1:length(ll),1:length(ll),doMatVec,ll )
そして私は得たError in ll[[x]] : subscript out of bounds
私がやろうとしていることの一般的な考え方について、Vectorizeで間違っているかもしれないと思いますが、ここで助けていただければ幸いです。plyr
/ -も見ていますが、dplyr
あまり成功していません。