|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Hi,
Does anyone know of a package in R that has a function to convert network data (e.g. an adjacency matrix or ) from 2-mode to 1-mode? I am conducting social network analysis. I know that Pajek has this function under Net --> Transform --> 2-mode to 1-mode --> Rows. I have searched the documentation under packages 'sna', 'network', 'igraph', and 'dynamicgraph' but I was not able to identify a comparable function. I would just export my data to Pajek and import it to R, but I'm going to have to generate hundreds of these graphs, so it would take quite a bit of time to do it this way. Thanks, Solomon [[alternative HTML version deleted]] ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
|
|
Re: For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Solomon, if i understand two-mode networks properly (they're bipartite, right?),
then this is not hard to do with igraph. Basically, for each vertex create an order=2 neighborhood, and then create a graph from the adjacency list, it is something like this: two.to.one <- function(g, keep) { neis <- neighborhood(g, order=2) neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) ## drop self-loops neis <- lapply(neis, function(x) x[ x %in% keep ]) ## keep only these neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) ## create edge lists neis[-keep-1] <- NULL ## these are not needed neis <- matrix(unlist(neis), byrow=TRUE, nc=2) ## a single edge list neis <- neis[ neis[,1] > neis[,2], ] ## count an edge once only mode(neis) <- "character" g2 <- graph.edgelist(neis, dir=FALSE) V(g2)$id <- V(g2)$name ## 'id' is used in Pajek g2 } It does not check that the graph is indeed two-mode, and it keeps the vertices given in the 'keep' argument. 'keep' is made of igraph vertex ids. You can use it like this: g <- graph.ring(10) keep <- seq(0,8,by=2) ## we keep the 'even' vertices g2 <- two.to.one(g, keep) write.graph(two.to.one(g, keep), format="pajek", file="/tmp/a.net") I haven't tested it much. We'll have a better function in the next igraph version. Gabor On Fri, May 09, 2008 at 03:37:05PM -0400, Messing, Solomon O. wrote: > Hi, > > > > Does anyone know of a package in R that has a function to convert > network data (e.g. an adjacency matrix or ) from 2-mode to 1-mode? I am > conducting social network analysis. I know that Pajek has this function > under Net --> Transform --> 2-mode to 1-mode --> Rows. I have searched > the documentation under packages 'sna', 'network', 'igraph', and > 'dynamicgraph' but I was not able to identify a comparable function. > > > > I would just export my data to Pajek and import it to R, but I'm going > to have to generate hundreds of these graphs, so it would take quite a > bit of time to do it this way. > > > > Thanks, > > > > Solomon > > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help@... mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. -- Csardi Gabor <csardi@...> UNIL DGM ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
|
|
Re: For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Hi Gabor,
Thank you for your help, and thanks for making the excellent igraph package. The function below seems not generate an edge list that works for my data. I coerced a my data from a data frame using graph.data.frame. You asked in your previous post if 2-mode networks are bipartite. I believe the answer is yes. However, in Hanneman, Robert A. and Mark Riddle. 2005. Introduction to social network methods. Riverside, CA: University of California, Riverside ( published in digital form at http://faculty.ucr.edu/~hanneman/ ) I found the following: "Two-mode data are sometimes stored in a second way, called the "bipartite" matrix. A bipartite matrix is formed by adding the rows as additional columns, and columns as additional rows." Did I need to convert my data frame to a bipartite matrix before applying the two.to.one function? Solomon >-----Original Message----- >From: Gabor Csardi [mailto:csardi@...] >Sent: Saturday, May 10, 2008 1:09 PM >To: Messing, Solomon O. >Cc: r-help@... >Subject: Re: [R] For Social Network Analysis-Graph Analysis - How to convert 2 >mode data to 1 mode data? > >Solomon, if i understand two-mode networks properly (they're bipartite, >right?), >then this is not hard to do with igraph. Basically, for each vertex create an >order=2 neighborhood, and then create a graph from the adjacency list, >it is something like this: > >two.to.one <- function(g, keep) { > neis <- neighborhood(g, order=2) > neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) ## drop >self-loops > neis <- lapply(neis, function(x) x[ x %in% keep ]) ## keep >only these > neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) ## create >edge lists > neis[-keep-1] <- NULL ## these >are not needed > neis <- matrix(unlist(neis), byrow=TRUE, nc=2) ## a >single edge list > neis <- neis[ neis[,1] > neis[,2], ] ## count >an edge once only > mode(neis) <- "character" > g2 <- graph.edgelist(neis, dir=FALSE) > V(g2)$id <- V(g2)$name ## 'id' >is used in Pajek > g2 >} > >It does not check that the graph is indeed two-mode, and it keeps the >vertices given in the 'keep' argument. 'keep' is made of igraph vertex ids. >You can use it like this: > >g <- graph.ring(10) >keep <- seq(0,8,by=2) ## we keep the 'even' vertices > >g2 <- two.to.one(g, keep) >write.graph(two.to.one(g, keep), format="pajek", file="/tmp/a.net") > >I haven't tested it much. We'll have a better function in the next igraph >version. >Gabor > >On Fri, May 09, 2008 at 03:37:05PM -0400, Messing, Solomon O. wrote: >> Hi, >> >> >> >> Does anyone know of a package in R that has a function to convert >> network data (e.g. an adjacency matrix or ) from 2-mode to 1-mode? I >> conducting social network analysis. I know that Pajek has this function >> under Net --> Transform --> 2-mode to 1-mode --> Rows. I have searched >> the documentation under packages 'sna', 'network', 'igraph', and >> 'dynamicgraph' but I was not able to identify a comparable function. >> >> >> >> I would just export my data to Pajek and import it to R, but I'm going >> to have to generate hundreds of these graphs, so it would take quite a >> bit of time to do it this way. >> >> >> >> Thanks, >> >> >> >> Solomon >> >> >> >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help@... mailing list >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> and provide commented, minimal, self-contained, reproducible code. > >-- >Csardi Gabor <csardi@...> UNIL DGM ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
|
|
Re: For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Hi Solomon,
On Tue, May 13, 2008 at 05:53:44PM -0400, Messing, Solomon O. wrote: > Hi Gabor, > > Thank you for your help, and thanks for making the excellent igraph > package. The function below seems not generate an edge list that works > for my data. I coerced a my data from a data frame using > graph.data.frame. > > You asked in your previous post if 2-mode networks are bipartite. I > believe the answer is yes. However, in > > Hanneman, Robert A. and Mark Riddle. 2005. Introduction to social > network methods. Riverside, CA: University of California, Riverside ( > published in digital form at http://faculty.ucr.edu/~hanneman/ ) > > I found the following: > > "Two-mode data are sometimes stored in a second way, called the > "bipartite" matrix. A bipartite matrix is formed by adding the rows as > additional columns, and columns as additional rows." > > Did I need to convert my data frame to a bipartite matrix before > applying the two.to.one function? No. The function i've sent assumes that your network is bipartite, i.e. if A and B are connected by an edge, then they're assumed to be different types of nodes. Just create the graph, calculate the 'keep' parameter, I assume that you know this from external information, and then call the function. G. > Solomon > > > >-----Original Message----- > >From: Gabor Csardi [mailto:csardi@...] > >Sent: Saturday, May 10, 2008 1:09 PM > >To: Messing, Solomon O. > >Cc: r-help@... > >Subject: Re: [R] For Social Network Analysis-Graph Analysis - How to > convert 2 > >mode data to 1 mode data? > > > >Solomon, if i understand two-mode networks properly (they're bipartite, > >right?), > >then this is not hard to do with igraph. Basically, for each vertex > create an > >order=2 neighborhood, and then create a graph from the adjacency list, > >it is something like this: > > > >two.to.one <- function(g, keep) { > > neis <- neighborhood(g, order=2) > > neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) > ## drop > >self-loops > > neis <- lapply(neis, function(x) x[ x %in% keep ]) > ## keep > >only these > > neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) > ## create > >edge lists > > neis[-keep-1] <- NULL > ## these > >are not needed > > neis <- matrix(unlist(neis), byrow=TRUE, nc=2) > ## a > >single edge list > > neis <- neis[ neis[,1] > neis[,2], ] > ## count > >an edge once only > > mode(neis) <- "character" > > g2 <- graph.edgelist(neis, dir=FALSE) > > V(g2)$id <- V(g2)$name > ## 'id' > >is used in Pajek > > g2 > >} > > > >It does not check that the graph is indeed two-mode, and it keeps the > >vertices given in the 'keep' argument. 'keep' is made of igraph vertex > ids. > >You can use it like this: > > > >g <- graph.ring(10) > >keep <- seq(0,8,by=2) ## we keep the 'even' vertices > > > >g2 <- two.to.one(g, keep) > >write.graph(two.to.one(g, keep), format="pajek", file="/tmp/a.net") > > > >I haven't tested it much. We'll have a better function in the next > igraph > >version. > >Gabor > > > >On Fri, May 09, 2008 at 03:37:05PM -0400, Messing, Solomon O. wrote: > >> Hi, > >> > >> > >> > >> Does anyone know of a package in R that has a function to convert > >> network data (e.g. an adjacency matrix or ) from 2-mode to 1-mode? I > am > >> conducting social network analysis. I know that Pajek has this > function > >> under Net --> Transform --> 2-mode to 1-mode --> Rows. I have > searched > >> the documentation under packages 'sna', 'network', 'igraph', and > >> 'dynamicgraph' but I was not able to identify a comparable function. > >> > >> > >> > >> I would just export my data to Pajek and import it to R, but I'm > going > >> to have to generate hundreds of these graphs, so it would take quite > a > >> bit of time to do it this way. > >> > >> > >> > >> Thanks, > >> > >> > >> > >> Solomon > >> > >> > >> > >> > >> [[alternative HTML version deleted]] > >> > >> ______________________________________________ > >> R-help@... mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-help > >> PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > >> and provide commented, minimal, self-contained, reproducible code. > > > >-- > >Csardi Gabor <csardi@...> UNIL DGM -- Csardi Gabor <csardi@...> UNIL DGM ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
|
|
|
|
|
Re: For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Consider the following two mode-data:
edgelist: actor event 1 Sam a 2 Sam b 3 Sam c 4 Greg a 5 Tom b 6 Tom c 7 Tom d 8 Mary b 9 Mary d Two-Mode Adjacency Matrix: a b c d Sam 1 1 1 0 Greg 1 0 0 0 Tom 0 1 1 1 Mary 0 1 0 1 To transform two mode to one mode data, we need a function that transforms the data like so: Sam is connected to Greg (via event a) Sam is connected to Tom (via event b and c) Sam is connected to Mary (via event b) Tom is connected to Mary (via event b and d) OK, now I load my data by executing the following: ################################################################################### require(igraph) df <- data.frame(actor = c('Sam','Sam','Sam','Greg','Tom','Tom','Tom','Mary','Mary'), event =c('a','b','c','a','b','c','d','b','d') ) g = graph.data.frame(df, directed=F) #Coerce data to igraph object 'g' #Loading Function two.to.one: ##two.to.one() transforms 2-mode data to 1-mode two.to.one <- function(g, keep) { neis <- neighborhood(g, order=2) neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) ## drop self-loops neis <- lapply(neis, function(x) x[ x %in% keep ]) ## keep only these neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) ## create edge lists neis[-keep-1] <- NULL ## these are not needed neis <- matrix(unlist(neis), byrow=TRUE, nc=2) ## a single edge list neis <- neis[ neis[,1] > neis[,2], ] ## count an edge once only mode(neis) <- "character" g2 <- graph.edgelist(neis, dir=FALSE) V(g2)$id <- V(g2)$name ## 'id' is used in Pajek g2 } #Actors are the first 4 verticies, set them to be kept: keep = V(g)[1:4] #Convert matrix with two.to.one: g2 = two.to.one(g, keep) g2 ################################################################################### This yields the following output: > g2 Vertices: 4 Edges: 2 Directed: FALSE Edges: [0] 3 -- 2 [1] 4 -- 1 But, this can't be right. Here there are only two edges where there should be four, and if I am inturpreting correctly, the output it is reporting that Tom is connected to Greg (he is not) and Sam is connected to Mary (which is true). When I load my function, which is designed to transform a two mode edgelist (e.g. two columns of data) into a one-mode adjacency matrix it seems to work: ################################################################################### #load my function df.to.nxn <- function( x, y ){ # x values will be the N x N values M <- matrix( nrow = length( unique( x ) ), ncol = length( unique( x ) ), dimnames = list( unique( x ), unique( x ) ) ) M[ 1:length( unique( x ) ), 1:length( unique( x ) ) ] <- 0 #initialize the values to 0 - this possibly could be removed for illustrative purposes for( i in 1:length( x ) ) { # iterate through rows of data index = which( y == y[i] ) M[ as.character( x[ index ] ), as.character( x[ index ] ) ] = 1 } M # return M, an N x N matrix } #Convert matrix g3 = df.to.nxn(df$actor, df$event) g4 = graph.adjacency(g3, mode = "undirected", diag = F) V(g4)$name = row.names(g3) g4 ################################################################################### This yields: > g4 Vertices: 4 Edges: 4 Directed: FALSE Edges: [0] Sam -- Greg [1] Sam -- Tom [2] Sam -- Mary [3] Tom -- Mary Which is what we wanted. I have not figured out how to weight edges yet (the Sam and Tom edge and the Tom and Mary edge should perhaps be weighted at 2 because 'connected twice' -- connected by two events). -Solomon ________________________________ From: Gabor Csardi [mailto:csardi@...] Sent: Wed 5/14/2008 4:01 AM To: Messing, Solomon O. Cc: R Help list Subject: Re: [R] For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data? Please stay on the list. On Tue, May 13, 2008 at 06:05:15PM -0400, Messing, Solomon O. wrote: > Gabor, > > By the way, this seems to work: I'm a bit lost. So now you're converting your data frame to a matrix? Why? Or you're doing the two-mode to one-mode conversion here? It does not seem so to me. Btw. there is a get.adjacency function in igraph to convert a graph to an adjacency matrix. G. > > df.to.nxn <- function( x, y ){ > # x values will be the N x N values > M <- matrix( nrow = length( unique( x ) ), ncol = length( unique( x > ) ), > dimnames = list( unique( x ), unique( x ) ) ) > M[ 1:length( unique( x ) ), 1:length( unique( x ) ) ] <- 0 > # initialize the values to 0 > for( i in 1:length( x ) ) { > # iterate through rows of data > index = which( y == y[i] ) > M[ as.character( x[ index ] ), as.character( x[ index ] > ) ] = 1 > } > M > # return M, an N x N matrix > } -- Csardi Gabor <csardi@...> UNIL DGM [[alternative HTML version deleted]] ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
|
|
Re: For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Solomon, sorry for the delay. In igraph vertices are numbered from 0, so you need
keep <- 0:3 and then the function i've sent seems to work. But i can see that you also have a solution now. Gabor On Sat, May 17, 2008 at 09:32:27AM -0400, Messing, Solomon O. wrote: > Consider the following two mode-data: > > edgelist: > actor event > 1 Sam a > 2 Sam b > 3 Sam c > 4 Greg a > 5 Tom b > 6 Tom c > 7 Tom d > 8 Mary b > 9 Mary d > > Two-Mode Adjacency Matrix: > a b c d > Sam 1 1 1 0 > Greg 1 0 0 0 > Tom 0 1 1 1 > Mary 0 1 0 1 > > To transform two mode to one mode data, we need a function that transforms the > data like so: > > Sam is connected to Greg (via event a) > Sam is connected to Tom (via event b and c) > Sam is connected to Mary (via event b) > Tom is connected to Mary (via event b and d) > > OK, now I load my data by executing the following: > ############################################################################### > #### > require(igraph) > df <- data.frame(actor = c > ('Sam','Sam','Sam','Greg','Tom','Tom','Tom','Mary','Mary'), > event =c('a','b','c','a','b','c','d','b','d') ) > g = graph.data.frame(df, directed=F) #Coerce data to igraph object 'g' > > #Loading Function two.to.one: > ##two.to.one() transforms 2-mode data to 1-mode > two.to.one <- function(g, keep) { > neis <- neighborhood(g, order=2) > neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) ## drop > self-loops > neis <- lapply(neis, function(x) x[ x %in% keep ]) ## keep > only these > neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) ## create > edge lists > neis[-keep-1] <- NULL ## these > are not needed > neis <- matrix(unlist(neis), byrow=TRUE, nc=2) ## a > single edge list > neis <- neis[ neis[,1] > neis[,2], ] ## count > an edge once only > mode(neis) <- "character" > g2 <- graph.edgelist(neis, dir=FALSE) > V(g2)$id <- V(g2)$name ## 'id' is used in Pajek > g2 > } > > #Actors are the first 4 verticies, set them to be kept: > keep = V(g)[1:4] > #Convert matrix with two.to.one: > g2 = two.to.one(g, keep) > g2 > ############################################################################### > #### > This yields the following output: > > g2 > Vertices: 4 > Edges: 2 > Directed: FALSE > Edges: > > [0] 3 -- 2 > [1] 4 -- 1 > > But, this can't be right. Here there are only two edges where there should be > four, and if I am inturpreting correctly, the output it is reporting that Tom > is connected to Greg (he is not) and Sam is connected to Mary (which is true). > > When I load my function, which is designed to transform a two mode edgelist > (e.g. two columns of data) into a one-mode adjacency matrix it seems to work: > ############################################################################### > #### > #load my function > df.to.nxn <- function( x, y ) > { # x values will be the N > x N values > M <- matrix( nrow = length( unique( x ) ), ncol = length( unique( x ) ), > dimnames = list( unique( x ), unique( x ) ) ) > M[ 1:length( unique( x ) ), 1:length( unique( x ) ) ] <- > 0 #initialize the values to 0 - this possibly could be > removed for illustrative purposes > for( i in 1:length( x ) ) > { # iterate through rows of > data > index = which( y == y[i] ) > M[ as.character( x[ index ] ), as.character( x[ index ] ) ] = > 1 > } > M > # return M, an N x N matrix > } > #Convert matrix > g3 = df.to.nxn(df$actor, df$event) > g4 = graph.adjacency(g3, mode = "undirected", diag = F) > V(g4)$name = row.names(g3) > g4 > ############################################################################### > #### > This yields: > > g4 > Vertices: 4 > Edges: 4 > Directed: FALSE > Edges: > > [0] Sam -- Greg > [1] Sam -- Tom > [2] Sam -- Mary > [3] Tom -- Mary > > Which is what we wanted. I have not figured out how to weight edges yet (the > Sam and Tom edge and the Tom and Mary edge should perhaps be weighted at 2 > because 'connected twice' -- connected by two events). > > -Solomon > > ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > From: Gabor Csardi [mailto:csardi@...] > Sent: Wed 5/14/2008 4:01 AM > To: Messing, Solomon O. > Cc: R Help list > Subject: Re: [R] For Social Network Analysis-Graph Analysis - How to convert 2 > mode data to 1 mode data? > > > Please stay on the list. > > On Tue, May 13, 2008 at 06:05:15PM -0400, Messing, Solomon O. wrote: > > Gabor, > > > > By the way, this seems to work: > > I'm a bit lost. So now you're converting your data frame > to a matrix? Why? Or you're doing the two-mode to one-mode > conversion here? It does not seem so to me. > > Btw. there is a get.adjacency function in igraph to convert > a graph to an adjacency matrix. > > G. > > > > > df.to.nxn <- function( x, y ){ > > # x values will be the N x N values > > M <- matrix( nrow = length( unique( x ) ), ncol = length( unique( x > > ) ), > > dimnames = list( unique( x ), unique( x ) ) ) > > M[ 1:length( unique( x ) ), 1:length( unique( x ) ) ] <- 0 > > # initialize the values to 0 > > for( i in 1:length( x ) ) { > > # iterate through rows of data > > index = which( y == y[i] ) > > M[ as.character( x[ index ] ), as.character( x[ index ] > > ) ] = 1 > > } > > M > > # return M, an N x N matrix > > } > > -- > Csardi Gabor <csardi@...> UNIL DGM > -- Csardi Gabor <csardi@...> UNIL DGM ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
|
|
Re: For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data?Hi Gabor,
Thanks for clearing that up. There still seems to be a problem, though. After executing: ############################################################################### require(igraph) df <- data.frame(actor = c ('Sam','Sam','Sam','Greg','Tom','Tom','Tom','Mary','Mary'), event =c('a','b','c','a','b','c','d','b','d') ) g = graph.data.frame(df, directed=F) #Coerce data to igraph object 'g' #Loading Function two.to.one: ##two.to.one() transforms 2-mode data to 1-mode two.to.one <- function(g, keep) { neis <- neighborhood(g, order=2) neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) ## drop self-loops neis <- lapply(neis, function(x) x[ x %in% keep ]) ## keep only these neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) ## create edge lists neis[-keep-1] <- NULL ## these are not needed neis <- matrix(unlist(neis), byrow=TRUE, nc=2) ## a single edge list neis <- neis[ neis[,1] > neis[,2], ] ## count an edge once only mode(neis) <- "character" g2 <- graph.edgelist(neis, dir=FALSE) V(g2)$id <- V(g2)$name ## 'id' is used in Pajek g2 } #Actors are the first 4 verticies, set them to be kept: keep = V(g)[1:4] #Convert matrix with two.to.one: g2 = two.to.one(g, keep) V(g2)$name = V(g)$name[1:4] g2 ##############################################################33 I get the following output: Vertices: 4 Edges: 4 Directed: FALSE Edges: [0] Sam -- Greg [1] Greg -- Tom [2] Greg -- Mary [3] Tom -- Mary This appears to be because the new igraph object is labeled correctly, but is not in order: > g2 = two.to.one(g, keep) > g2 Vertices: 4 Edges: 4 Directed: FALSE Edges: [0] 1 -- 0 [1] 0 -- 2 [2] 0 -- 3 [3] 2 -- 3 > V(g2)$name [1] "1" "0" "2" "3" So when I try to label the new object, the labels are assigned to the verticies incorrectly. What is the best solution? Could I create a new graph by ordering g2 by id? Thanks, Solomon ________________________________ From: Gabor Csardi [mailto:csardi@...] Sent: Tue 5/20/2008 3:08 AM To: Messing, Solomon O. Cc: R Help list Subject: Re: [R] For Social Network Analysis-Graph Analysis - How to convert 2 mode data to 1 mode data? Solomon, sorry for the delay. In igraph vertices are numbered from 0, so you need keep <- 0:3 and then the function i've sent seems to work. But i can see that you also have a solution now. Gabor On Sat, May 17, 2008 at 09:32:27AM -0400, Messing, Solomon O. wrote: > Consider the following two mode-data: > > edgelist: > actor event > 1 Sam a > 2 Sam b > 3 Sam c > 4 Greg a > 5 Tom b > 6 Tom c > 7 Tom d > 8 Mary b > 9 Mary d > > Two-Mode Adjacency Matrix: > a b c d > Sam 1 1 1 0 > Greg 1 0 0 0 > Tom 0 1 1 1 > Mary 0 1 0 1 > > To transform two mode to one mode data, we need a function that transforms the > data like so: > > Sam is connected to Greg (via event a) > Sam is connected to Tom (via event b and c) > Sam is connected to Mary (via event b) > Tom is connected to Mary (via event b and d) > > OK, now I load my data by executing the following: > ############################################################################### > #### > require(igraph) > df <- data.frame(actor = c > ('Sam','Sam','Sam','Greg','Tom','Tom','Tom','Mary','Mary'), > event =c('a','b','c','a','b','c','d','b','d') ) > g = graph.data.frame(df, directed=F) #Coerce data to igraph object 'g' > > #Loading Function two.to.one: > ##two.to.one() transforms 2-mode data to 1-mode > two.to.one <- function(g, keep) { > neis <- neighborhood(g, order=2) > neis <- lapply(seq(neis), function(x) neis[[x]][ neis[[x]] != x-1]) ## drop > self-loops > neis <- lapply(neis, function(x) x[ x %in% keep ]) ## keep > only these > neis <- lapply(seq(neis), function(x) t(cbind(x-1, neis[[x]]))) ## create > edge lists > neis[-keep-1] <- NULL ## these > are not needed > neis <- matrix(unlist(neis), byrow=TRUE, nc=2) ## a > single edge list > neis <- neis[ neis[,1] > neis[,2], ] ## count > an edge once only > mode(neis) <- "character" > g2 <- graph.edgelist(neis, dir=FALSE) > V(g2)$id <- V(g2)$name ## 'id' is used in Pajek > g2 > } > > #Actors are the first 4 verticies, set them to be kept: > keep = V(g)[1:4] > #Convert matrix with two.to.one: > g2 = two.to.one(g, keep) > g2 > ############################################################################### > #### > This yields the following output: > > g2 > Vertices: 4 > Edges: 2 > Directed: FALSE > Edges: > > [0] 3 -- 2 > [1] 4 -- 1 > > But, this can't be right. Here there are only two edges where there should be > four, and if I am inturpreting correctly, the output it is reporting that Tom > is connected to Greg (he is not) and Sam is connected to Mary (which is true). > > When I load my function, which is designed to transform a two mode edgelist > (e.g. two columns of data) into a one-mode adjacency matrix it seems to work: > ############################################################################### > #### > #load my function > df.to.nxn <- function( x, y ) > { # x values will be the N > x N values > M <- matrix( nrow = length( unique( x ) ), ncol = length( unique( x ) ), > dimnames = list( unique( x ), unique( x ) ) ) > M[ 1:length( unique( x ) ), 1:length( unique( x ) ) ] <- > 0 #initialize the values to 0 - this possibly could be > removed for illustrative purposes > for( i in 1:length( x ) ) > { # iterate through rows of > data > index = which( y == y[i] ) > M[ as.character( x[ index ] ), as.character( x[ index ] ) ] = > 1 > } > M > # return M, an N x N matrix > } > #Convert matrix > g3 = df.to.nxn(df$actor, df$event) > g4 = graph.adjacency(g3, mode = "undirected", diag = F) > V(g4)$name = row.names(g3) > g4 > ############################################################################### > #### > This yields: > > g4 > Vertices: 4 > Edges: 4 > Directed: FALSE > Edges: > > [0] Sam -- Greg > [1] Sam -- Tom > [2] Sam -- Mary > [3] Tom -- Mary > > Which is what we wanted. I have not figured out how to weight edges yet (the > Sam and Tom edge and the Tom and Mary edge should perhaps be weighted at 2 > because 'connected twice' -- connected by two events). > > -Solomon > > ??????????????????????????????????????????????????????????????????????????????? > From: Gabor Csardi [mailto:csardi@...] > Sent: Wed 5/14/2008 4:01 AM > To: Messing, Solomon O. > Cc: R Help list > Subject: Re: [R] For Social Network Analysis-Graph Analysis - How to convert 2 > mode data to 1 mode data? > > > Please stay on the list. > > On Tue, May 13, 2008 at 06:05:15PM -0400, Messing, Solomon O. wrote: > > Gabor, > > > > By the way, this seems to work: > > I'm a bit lost. So now you're converting your data frame > to a matrix? Why? Or you're doing the two-mode to one-mode > conversion here? It does not seem so to me. > > Btw. there is a get.adjacency function in igraph to convert > a graph to an adjacency matrix. > > G. > > > > > df.to.nxn <- function( x, y ){ > > # x values will be the N x N values > > M <- matrix( nrow = length( unique( x ) ), ncol = length( unique( x > > ) ), > > dimnames = list( unique( x ), unique( x ) ) ) > > M[ 1:length( unique( x ) ), 1:length( unique( x ) ) ] <- 0 > > # initialize the values to 0 > > for( i in 1:length( x ) ) { > > # iterate through rows of data > > index = which( y == y[i] ) > > M[ as.character( x[ index ] ), as.character( x[ index ] > > ) ] = 1 > > } > > M > > # return M, an N x N matrix > > } > > -- > Csardi Gabor <csardi@...> UNIL DGM > -- Csardi Gabor <csardi@...> UNIL DGM [[alternative HTML version deleted]] ______________________________________________ R-help@... mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. |
| Free Forum Powered by Nabble | Forum Help |