2012-06-30 2 views
1

igraph를 사용하여 공동 저자 네트워크를 만들고 싶습니다.공동 작성자 네트워크 만들기

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

할 어쨌든 거기 :

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')) 

내가 다음과 같습니다 에지 목록을 작성하고 싶습니다 :

내 데이터처럼 보이는 data.frame으로 구성됩니다 (예 : 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]) 

`` 도움을 주시면 감사하겠습니다. (이전에 다른 제목 아래에이 질문을 게시했지만 충분히 명확하지 않다고 말합니다.)

답변

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) 
+0

고마운. 정확히 내가 필요로했던 것 – user1043144

3

코드는 "용지"열을 반복하므로 사용자가 제공 한 데이터를 생성하지 않습니다. 또한 기존 개체에 추가 할 때마다 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 초는 나에게 꽤 합리적인 것 같다 당신의 출력을 보면, 내가이 생각하는 당신이 원하는 무엇을합니까?

+0

당신을 감사합니다. 나는 게시에서 많은 것을 배웠다 – user1043144

관련 문제