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@rmki.kfki.hu]
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@rmki.kfki.hu]
> 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@rmki.kfki.hu>    UNIL DGM
>

--
Csardi Gabor <csardi@rmki.kfki.hu>    UNIL DGM



	[[alternative HTML version deleted]]

