5

私は、2 レベルのネストされたリストの操作を含むigraph (ランダム グラフのライブラリ)を使用して、 Rで信号伝搬アルゴリズムに取り組んでいます。

Igraph では、属性を頂点 (グラフのノード) にアタッチできます。これらはベクトルまたはリストにすることができますが、私のアプリケーションではネストされたリストが必要です。

確認するには、次を試してください。

library("igraph")
g <- graph.full(10) # create a fully connected graph with 10 vertices
V(g)$letters <- list(NULL) # adds a list called "letters" to every vertex
V(g)$letters # results in a nested list

さまざまな段階で、ベクトルに格納されているいくつかの事前定義された要素を、サブセット化されたリストがベクトルと同じサイズである第 2 レベル リストの特定のサブセットに追加したいと思います。

問題は、第 2 レベルのリストに要素を追加する効率的な方法を見つけることです。

より簡単な (そしてこれまでのところ唯一の) 方法は、ループを作成することです。

set.seed(1234)

# every iteration represents a "round" of element addition ,
# followed by other operations. 
# So the attribute "letters" should not be populated in one sitting.
for (i in 1:10){

  # select randomly five 2nd-level lists (vertices) from the 1st-level list
  # the selected vertices are generated randomly for exposition, 
  # but I need to be able to select them from a well-defined vector (sel.ver)

  sel.vert <- sample(1:10, 5)

  # generate elements to add to the lists in the 2nd-level list (vertices)
  # again, i generate them randomly just to fill the vector, 
  #but the vector could be pre-determined

  add.elem <- sample(letters, 5)

  # now add add each element to its own list
  # notice that the first ELEMENT of add.elem (add.elem[1]) is added
  # to the attribute of the first SELECTED vertex (V(g)[sel.vert[1]]$letters,
  # the second element of add.elem with the second SELECTED vertex, and so on..

  for (l in 1:5){
    V(g)[sel.vert[l]]$letters <- list(c(V(g)[sel.vert[l]]$letters, add.elem[l]))    
  }
}

(経験豊富な読者には、これが悪いプログラミング プラクティスのホラー ショーであったことをお詫びします)

初期ネットワークのサイズが大きくなり、反復ごとに (5 ではなく乱数で) より多くの頂点が選択されると、ループは非常に遅くなります。これは「主力」機能のはずなので、スピードアップしたいと思います。

Rのベクトルまたはリストに要素を効率的に追加または削除しますか?」、つまり、可能な限りベクトルを操作し、それらのサイズを事前に割り当てますが、私の場合には当てはまらないと思います。

  1. igraphではリストを使うしかないと思います(少なくとも最初のレベルでは)
  2. 第 2 レベルでは、ランダムに選択された頂点に応じて、リストの最終的な長さが異なります。そのため、正しいサイズのベクトルを事前に割り当てることは困難です。非常に大きなベクトルを 2 番目のレベルに配置したとしても、最初は NA で埋められていて (結果としてベクトルのリストが生成されます)、どの位置に要素を追加すればよいかわかりません (反復時のリストの長さはランダムであるため)。後で NA を削除する必要があることは言うまでもありません。

これは、要素を追加する (操作する) ネストされたリストの特定のケースである必要があります。ddplyそのため、内側のループをin plyrまたはに置き換えることで、より高速な実装が実現できるのではないかと思いますが、do.call適用する関数を書くことができませんでした。get the elements of the (inner) list and add this new element (itself a subset of a vector)

コメントや提案は大歓迎です。投稿が明確であることを願っています。

4

1 に答える 1

2
# number of vertices to add elements to at a time
nv <- 5

# selected vertices and elements
sel.ver <- sample(V(g), nv)
add.elem <- sample(letters, nv)

V(g)$letters[sel.ver] <- lapply(1:nv, function(x) {
  c(add.elem[x], unlist(V(g)$letters[sel.ver[x]]))
})
于 2012-08-14T19:24:01.820 に答える