Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Let's take a look at representing a network in R using the network object from the statnet Statnet package. To get the statnet Statnet package, see R Toolkit.

We'll construct a 4 level network – a root, some departments, some people in each department and some grants of each of the people. We'll add attributes to these objects and display the results.

...

We need to start somewhere. Let's create a new network called "net" with a single node or vertex.

noformat
Panel
No Format
 #
 #
 Learning to use network and network plotting functions for VIVO data

#

 #
 # M. Conlon April 11,
2011
#start with a root node
net
 2011
 #
 # 
 # start with a root node
 net <-network.initialize(1,directed=F)


 net %v% "type" <- "Root"


 net %v% "vertex.names" <- "COM"


 net %v% "amt" <-0



That's

...

all

...

you

...

need

...

to

...

create

...

a

...

single

...

node

...

network

...

with

...

some

...

attributes.

...

The

...

network

...

has

...

one

...

node

...

with

...

name

...

"COM"

...

(that's

...

short

...

for

...

"College

...

of

...

Medicine"

...

at

...

UF).

...

The

...

%v%

...

lines

...

set

...

various

...

attribute

...

lists

...

to

...

singleton

...

values.

...

Here

...

I've

...

started

...

a

...

"type"

...

attribute

...

to

...

differentiate

...

the

...

types

...

of

...

things

...

that

...

will

...

be

...

in

...

this

...

network

...

Departments,

...

people,

...

grants,

...

and

...

a

...

single

...

root

...

vertex.

...

The

...

amt

...

attribute

...

will

...

hold

...

dollar

...

amounts

...

for

...

grants

...

and

...

totals

...

for

...

grants

...

at

...

other

...

levels

...

in

...

the

...

network.

...

Adding

...

Departments

...

to

...

the

...

Network

...

Next,

...

let's

...

create

...

three

...

departments.

...

Two

...

lines

...

of

...

code

...

are

...

needed

...

for

...

each

...

department.

...

First,

...

add

...

a

...

vertex

...

to

...

the

...

network.

...

Note

...

that

...

that

...

the

...

same

...

attributes

...

are

...

being

...

set

...

for

...

each

...

vertex

...

type,vertex.names

...

and

...

amt.

...

Second,

...

the

...

vertex

...

is

...

linked

...

to

...

the

...

root

...

by

...

asserting

...

an

...

edge

...

connecting

...

the

...

department

...

to

...

the

...

root.

No Format
 # 
{panel}
 #

...

 create some departments

...


 #

...


 add.vertices(net,1,list(list(type="Department",vertex.names="Radiology",amt=0)))

...


 net["COM","Radiology"]<-1

...


 add.vertices(net,1,list(list(type="Department",vertex.names="Pathology",amt=0)))

...


 net["COM","Pathology"]<-1

...


 add.vertices(net,1,list(list(type="Department",vertex.names="Pediatrics",amt=0)))

...


 net["COM","Pediatrics"]<-1
No Format

{panel}
Edge assertions are simple matrix element assignments in an edge matrix with the same name as the network object.  This is all provided by the statnet package.  From  and to are specified by vertex names.  The value "1" indicates an edge between the vertices.

There is much more that can be done with edges and edge attributes.  We are keeping things simple here.
h1. Adding People to the Departments
Let's add people to each of the departments.  We use the same method as previously -- create a vertex for each person and connect it to the department vertex.
{panel}
 

...


Edge assertions are simple matrix element assignments in an edge matrix with the same name as the network object. This is all provided by the statnet package. From and to are specified by vertex names. The value "1" indicates an edge between the vertices.

There is much more that can be done with edges and edge attributes. We are keeping things simple here.

Adding People to the Departments

Let's add people to each of the departments. We use the same method as previously – create a vertex for each person and connect it to the department vertex.

No Format
 #
 # create some people in the departments
 #
 

...

add.vertices(net,1,list(list(type="Person",vertex.names="Mancuso",amt=0)))

...


 net["Radiology","Mancuso"]<-1

...


 add.vertices(net,1,list(list(type="Person",vertex.names="Sistrom",amt=0)))

...


 net["Radiology","Sistrom"]<-1

...

 
 add.vertices(net,1,list(list(type="Person",vertex.names="Rathe",amt=0)))

...


 net["Radiology","Rathe"]<-1

...

 

...

There.

...

We

...

have

...

added

...

three

...

people

...

to

...

the

...

Radiology

...

Department.

...

In

...

the

...

code

...

below,

...

we

...

first

...

add

...

15

...

people

...

to

...

Pathology

...

and

...

30

...

people

...

to

...

Pediatrics.

...

We

...

use

...

an

...

R

...

loop

...

to

...

repetitively

...

add

...

the

...

vertices

...

and

...

edges.

...

We

...

generate

...

a

...

"name"

...

for

...

each

...

person

...

using

...

the

...

R

...

paste

...

function.

...

The

...

people

...

in

...

Pathology

...

will

...

be

...

named

...

P1,

...

P2,

...

...

...

P15.

...

The

...

people

...

in

...

Pediatrics

...

will

...

be

...

named

...

M1,

...

M2,

...

...

...

M30.

...

Experienced

...

R

...

programmers

...

will

...

ask

...

"Do

...

we

...

need

...

loops?

...

Why

...

not

...

add

...

all

...

the

...

Pediatric

...

vertices

...

at

...

once

...

and

...

then

...

all

...

the

...

Pediatric

...

edges

...

at

...

once?"

...

And

...

the

...

answer

...

is

...

"Of

...

course."

...

We

...

have

...

simplified

...

the

...

code

...

for

...

the

...

presentation

...

here.

...

R

...

programmers

...

would

...

figure

...

out

...

how

...

to

...

add

...

15

...

Pediatric

...

people

...

in

...

two

...

lines

...

one

...

for

...

vertices

...

and

...

one

...

for

...

edges.

...

No Format
 for 

...

(i in 1:15) {

...


   name <- paste("P",i,sep="")

...


   add.vertices(net,1,list(list(type="Person",vertex.names=name,amt=0)))

...


   net["Pathology",name]<-1

...


 }

...


 for (i in 1:30) {

...


   name <- paste("M",i,sep="")

...


   add.vertices(net,1,list(list(type="Person",vertex.names=name,amt=0)))

...


   net["Pediatrics",name]<-1

...


 }
No Format

{panel}

h1. Adding Grants for each person
Finally, we wish to add grant vertices and an edge connecting the grant vertex to a corresponding person.  Each grant will have a name (again automatically generated) and an award amount.  In the example, the award amount is stored in the attribute "amt".  We generate award amounts as a random number.

We have a bit of a conundrum.  In our previous work, we explicitly added code for for each department and then for each department, we wrote code to add people to the department.  It's not feasible to write code for each person on the network to add their grants. Even in the simple work we are presenting here, we now have 48 people in the network.  How do we proceed?

The code sample below begins by creating three vectors of the attributes of the nodes creates so far -- vt stores types, vn stores names and va stores amounts (all zero so far, we have't added any grants yet).

The rest of the code is two nested loops.  The outer loop scans the entire network looking for Person nodes.  When a Person nodes is found, a number of grants (ng) is generated as a random from 0 to 9 using the R runif function.

Then an inner loop processes each grant:
* A grant name is generated
* A grant amount is generated using the R function rexp.
* And then the grant is added to the network just as the previous nodes were added -- a call to call.vertices followed by adding an edge connecting the grant to the person.

Following the addition of the grant to the network, three short sequences of code update the amt total for the corresponding person, department and root nodes.  The amounts are retrieved, the corresponding amt is added and the amounts are put back in the network object.

Again, an experienced R programmer could remove steps. The code shown here is designed for clarity, not conciseness nor speed.

{panel}
 

...


Adding Grants for each person

Finally, we wish to add grant vertices and an edge connecting the grant vertex to a corresponding person. Each grant will have a name (again automatically generated) and an award amount. In the example, the award amount is stored in the attribute "amt". We generate award amounts as a random number.

We have a bit of a conundrum. In our previous work, we explicitly added code for for each department and then for each department, we wrote code to add people to the department. It's not feasible to write code for each person on the network to add their grants. Even in the simple work we are presenting here, we now have 48 people in the network. How do we proceed?

The code sample below begins by creating three vectors of the attributes of the nodes creates so far – vt stores types, vn stores names and va stores amounts (all zero so far, we have't added any grants yet).

The rest of the code is two nested loops. The outer loop scans the entire network looking for Person nodes. When a Person nodes is found, a number of grants (ng) is generated as a random from 0 to 9 using the R runif function.

Then an inner loop processes each grant:

  • A grant name is generated
  • A grant amount is generated using the R function rexp.
  • And then the grant is added to the network just as the previous nodes were added – a call to call.vertices followed by adding an edge connecting the grant to the person.

Following the addition of the grant to the network, three short sequences of code update the amt total for the corresponding person, department and root nodes. The amounts are retrieved, the corresponding amt is added and the amounts are put back in the network object.

Again, an experienced R programmer could remove steps. The code shown here is designed for clarity, not conciseness nor speed.

No Format
 #
 # Add grants as another level
 #
 vt<-get.vertex.attribute(net,"type")

...


 vn<-get.vertex.attribute(net,"vertex.names")

...


 va<-get.vertex.attribute(net,"amt")

...



 for (i in 1:network.size(net)) {

...


   if (vt

...

[i] == "Person")

...

 {
     di<-get.neighborhood(net,i)[1]  # get department index for this

...

 person
     ng <- floor(10*runif(1))

...

   
     if (ng > 0)

...

 {
       for (j in 1:ng)

...

 {
         gname <- paste(vn[i],".G",j,sep="")

...


         gamt=floor(50000*rexp(1)*rexp(1))

...


         add.vertices(net,1,list(list(type="Grant",vertex.names=gname,amt=gamt)))

...


         net[vn[i],gname]<-1

...


 #
 # Add the grant amounts to the corresponding person grant total
 #
         va<-get.vertex.attribute(net,"amt")

...


         va[i]<-va[i]+gamt

...


         set.vertex.attribute(net,"amt",va)

...


 #
 # Add the grant amounts to the corresponding department total
 #
         va<-get.vertex.attribute(net,"amt")

...


         va[di]<-va[di]+gamt

...


         set.vertex.attribute(net,"amt",va)

...


 #
 # Add the grant amount to the root total
 #
         va<-get.vertex.attribute(net,"amt")

...


         va[1]<-va[1]+gamt

...


         set.vertex.attribute(net,"amt",va)

...


...

 

...

 

...

 

...

 

...

   }
     }
   }
 } 

Whew. We not only added grants to each person, we created grant totals for persons, departments and the root (the collection of all departments). These grant totals represent the total number of dollars awarded to the person, to the persons in a department and to all the persons in all the departments. These totals will be very valuable in making displays and reports from the data.

Displaying the results

Now we can display the network using the built-in features of R and the statnet package. A plot can be generated with a single statement:

No Format
 plot(net)

The result is shown below:

Default network visualization

Image Added

All the nodes are the same color. Perhaps we'd like to see the grants colored differently from the people and so on. This is easily done. The plot() function can use vertex attributes to control display. For example:

No Format
 

...

No Format

{panel}
The result is shown below:

!Simple.png! Default network visualization


All the nodes are the same color.  Perhaps we'd like to see the grants colored differently from the people and so on.  This is easily done.  The plot() function can use vertex attributes to control display.  For example:

{panel}
 
plot(net,vertex.col="type")
No Format

{panel}
The result is shown below:

!VerticesByType.png! Vertices colored by type. Departments are black.  The root is blue


Finally, the code below assigns colors to vertices using the R palette functions (a rainbow palette).  The plot displays the size of each node based on the value of the vertex attribute amt.  So the root node will be biggest.  A formula is used to scale the node sizes based on the log of grant dollars -- so 1 million dollars has size "6", a one thousand dollar grant has size "3", and so on.
{panel}
 

...


The result is shown below:

Image Added

Vertices colored by type. Departments are black. The root is blue

Finally, the code below assigns colors to vertices using the R palette functions (a rainbow palette). The plot displays the size of each node based on the value of the vertex attribute amt. So the root node will be biggest. A formula is used to scale the node sizes based on the log of grant dollars – so 1 million dollars has size "6", a one thousand dollar grant has size "3", and so on.

No Format
 #
 #  generate a plot of departments, people and grants
 #

 

...

palette(rev(rainbow(6)))

...


 plot(net,vertex.col="type",

...


   vertex.cex=0.25*(1+floor(log10(1+get.vertex.attribute(net,"amt")))))

...


The result is shown below:

Image Modified

Vertices by Type and Amt. Larger vertices represent more grant dollars. Note some very small "people" vertices – these have no associated grants and therefore no grant dollars.

R and statnet provide many more options for displaying graphs and networks. If you are not familiar with R, you will want to review the help system regarding the plot function and the par (graphical parameters) function. It is straightforward to display labels, control the presentation of edges, use different shapes for vertices and much more.

Summary

...

The code provided here is for idea generation. What attributes would be good to show on such a plot? What other plots can be made? How would we display publications? Or multi-level organizational structure?

...