在 R 中不循环地对连续的列表元素对应用函数

wms*_*ith 5 r vectorization igraph

我试图找到一种有效的(即避免使用循环)方法来应用一个函数,该函数迭代地将列表的当前和前一个(或下一个)元素作为参数,并返回结果列表(其长度必然是短 1 个元素)。作为一个具体的例子,

我有一个在某些图中定义路径的顶点列表

vlist <- c(1,2,7,12,17)
Run Code Online (Sandbox Code Playgroud)

来自使用 igraph 函数“lattice”构建的点阵图

G <- graph.lattice(c(5,7))
Run Code Online (Sandbox Code Playgroud)

我想在 vlist 上应用函数“get.edge.ids”,以便返回的列表产生连接 vlist 中连续元素的边的 id。例如,我想要边 1-->2、2-->7、7-->12、12-->17 的 id

使用 for 循环这很简单,

    findEids <- function(G,vlist) {
        outlist=c()
        for (i in 1:(length(vlist)-1) {
            outlist=append(outlist,get.edge.ids(G,c(vlist[i],vlist[i+1])))
        }
        return(outlist)
    }
Run Code Online (Sandbox Code Playgroud)

但我想使用像 apply() 或 reduce() 这样的矢量化方法来看看是否可以让它更快地工作,因为我需要从脚本中重复调用这样的函数(例如,计算总拉伸)对于 G 的生成树)。

bpe*_*ter 4

我用mapply这个。例如

a<-1:1000
mapply(function(x,y)x-y,a[-1000],a[-1])
Run Code Online (Sandbox Code Playgroud)

它似乎比 for 循环版本稍快:

> f <- function(x,y)x-y
> g <- function(){
     o<-c();
     for(i in a[-1000])o<-c(o,f(i,i+1))
> }


>
> system.time( 
+     for(i in 1:1000){
+         mapply(f,a[-1000],a[-1])
+     }
+ )
   user  system elapsed 
  2.344   0.000   2.345 


> system.time(for(i in 1:1000)g())
   user  system elapsed 
  3.399   0.000   3.425 
Run Code Online (Sandbox Code Playgroud)