我正在尝试通过用户定义的函数计算矩阵的每个元素。我使用了双for
循环、嵌套sapply
和apply
之后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
- 没有太大的成功。