0

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

4

0 回答 0