1

igraphを使って共著ネットワークを作りたいです。

私のデータは、次のようなdata.frameに編成されています。

DF1 <- cbind(Papers =  paste('Paper', 1:5, sep = ''),
             Author1 = c('A', 'D', 'C', 'C', 'C'),
             Author2 = c('B', 'C', 'F', NA, 'F'),
             Author3 = c('C', 'E', NA, NA, 'D'))

次のようなエッジリストを作成したいと思います。

   Vertex1 Vertex2
        A       B
        D       C
        C       F
        C       F
        A       C
        D       E
        C       D
        B       C
        C       E
        F       D

とにかくRでこれを行うことはありますか(たとえばigraph)

次の関数でうまくいきますが、大規模なデータセット(5,000以上の論文)の場合、実行に時間がかかりすぎます

Fun_DFtoEdgeList <- function (Inputdataframe)
{

  ## This function create an edge list to create a network
  ## Input : Dataframe with UNIQUE VALUES !!!!

  ResEdgeList <- data.frame(Vertex1 = c('--'), Vertex2 = c('--'))


  for (i in 1 : (ncol(Inputdataframe)-1))
  {
    for (j in 2: (ncol(Inputdataframe)))
    {
      if (i !=j)     
      {
        #print(paste(i, j, sep ='--'))

        ToAppend <- data.frame(cbind(Inputdataframe[,i], Inputdataframe[,j]))
        names(ToAppend) <- names(ResEdgeList)
        #print(ToAppend)

        ResEdgeList <- rbind(ResEdgeList, ToAppend)
      }
    }

  }

  ResEdgeList <- data.frame(ResEdgeList[-1,], stringsAsFactors = FALSE)
  ResEdgeList<- subset(ResEdgeList, (is.na(Vertex1) == FALSE ) & (is.na(Vertex2) == FALSE ))  
  ResEdgeList
}


Fun_DFtoEdgeList (DF1[,-1])

``助けていただければ幸いです。(私は以前にこの質問を別の見出しで投稿していましたが、十分に明確ではなかったと言われています)

4

2 に答える 2

3

「Paper」列を繰り返し処理しているため、コードは指定したデータを生成しません。また、既存のオブジェクトに追加するたびに、R はオブジェクト全体の別のコピーを取得する必要があるため、遅いことがわかります...これを繰り返し行うと、速度が低下します。あなたの出力を見ると、これはあなたが望むことだと思います:

#First, creat all combos of the columns you want. I don't think you want to include the "Paper" column?

x <- combn(2:4,2)
#-----
     [,1] [,2] [,3]
[1,]    2    2    3
[2,]    3    4    4

#next use apply to go through each pair:
apply(x, 2, function(z) data.frame(Vertex1 = DF1[, z[1]], Vertex2 = DF1[, z[2]]))
#-----
[[1]]
  Vertex1 Vertex2
1       A       B
2       D       C
3       C       F
4       C    <NA>
5       C       F
....
#So use do.call to rbind them together:

out <- do.call("rbind", 
        apply(x, 2, function(z) data.frame(Vertex1 = DF1[, z[1]], Vertex2 = DF1[, z[2]])))

#Finally, filter out the rows with NA:
out[complete.cases(out),]
#-----
   Vertex1 Vertex2
1        A       B
2        D       C
3        C       F
5        C       F
6        A       C
7        D       E
10       C       D
11       B       C
12       C       E
15       F       D

最後に、これがより大きな問題にどのようにスケールするかを見てください。

#Just over a million papers
zz <- matrix(sample(letters, 1000002, TRUE), ncol = 3)
x <- combn(1:3, 2)
system.time(do.call("rbind", 
                    apply(x, 2, function(z) data.frame(Vertex1 = zz[, z[1]], Vertex2 = zz[, z[2]]))))
#-----
user  system elapsed 
  1.332   0.144   1.482

1.5秒は私にはかなり合理的ですか?

于 2012-06-30T15:30:56.980 に答える
1

これを行うためのより良い方法があるかもしれませんが、試しcombnてみると、すべての一意の組み合わせが生成されます。

DF1 <- cbind(Papers =  paste('Paper', 1:5, sep = ''),
             Author1 = c('A', 'D', 'C', 'C', 'C'),
             Author2 = c('B', 'C', 'F', NA, 'F'),
             Author3 = c('C', 'E', NA, NA, 'D'))

require(igraph)
l=apply(DF1[,-1],MARGIN=1,function(x) na.omit(data.frame(t(combn(x,m=2)))))
df=do.call(rbind,l)
g=graph.data.frame(df,directed=F)
plot(g)
于 2012-06-30T15:37:09.523 に答える