简体   繁体   中英

Creating two-mode network from binary and character variables in data frame

SNA folks: I am trying to create a two-mode.network from a data frame in R. I have a list of organizations which are connected via common membership in a parent organization. I have membership in that organization coded in a binary variable. I have successfully created a sociomatrix and subsequent.network object based on those data via the following code (from Create adjacency matrix based on binary variable ):

library(statnet)
org <- c("A","B","C","D","E","F","G","H","I","J")
link <- c(1,0,0,0,1,1,0,0,1,1)
person <- c("Mary","Michael","Mary","Jane","Jimmy",
            "Johnny","Becky","Bobby","Becky","Becky")

df <- data.frame(org,link,person)

socmat1 <- tcrossprod(df$link)
rownames(socmat1) <- df$org
colnames(socmat1) <- df$org
diag(socmat1) <- 0
socmat1
#>   A B C D E F G H I J
#> A 0 0 0 0 1 1 0 0 1 1
#> B 0 0 0 0 0 0 0 0 0 0
#> C 0 0 0 0 0 0 0 0 0 0
#> D 0 0 0 0 0 0 0 0 0 0
#> E 1 0 0 0 0 1 0 0 1 1
#> F 1 0 0 0 1 0 0 0 1 1
#> G 0 0 0 0 0 0 0 0 0 0
#> H 0 0 0 0 0 0 0 0 0 0
#> I 1 0 0 0 1 1 0 0 0 1
#> J 1 0 0 0 1 1 0 0 1 0

testnet <- as.network(x = socmat1,
                  directed = FALSE,
                  loops = FALSE,
                  matrix.type = "adjacency"
)
testnet
#>  Network attributes:
#>   vertices = 10 
#>   directed = FALSE 
#>   hyper = FALSE 
#>   loops = FALSE 
#>   multiple = FALSE 
#>   bipartite = FALSE 
#>   total edges= 10 
#>     missing edges= 0 
#>     non-missing edges= 10 
#> 
#>  Vertex attribute names: 
#>     vertex.names 
#> 
#> No edge attributes

Created on 2020-10-24 by the reprex package (v0.3.0)

However, I obviously can't use tcrossprod() similarly to achieve the same result with individuals connected by organizations or vice versa, as shown by the following code:

socmat2 <- tcrossprod(df$org)
#> Error in df$org: object of type 'closure' is not subsettable
rownames(socmat2) <- df$person
#> Error in df$person: object of type 'closure' is not subsettable
colnames(socmat2) <- df$person
#> Error in df$person: object of type 'closure' is not subsettable
diag(socmat2) <- 0
#> Error in diag(socmat2) <- 0: object 'socmat2' not found
socmat2
#> Error in eval(expr, envir, enclos): object 'socmat2' not found

How can I create a two-mode.network with the first set of edges being an organization's membership in the larger organization (denoted by the link variable) and the second being an individual's leadership position in an organization?

Thanks, all.

Created on 2020-10-24 by the reprex package (v0.3.0)

There are many different ways to do what you're trying to do. I don't know of any function that magically creates a two-mode.network based on the data you have, so the solution below involves a bit of data manipulation. We first create a data frame with the nodes, then another one with the edges. Then use nodes and edges as inputs to create a network object. The code is self-explanatory:

library(tidyverse)
library(network)

# Let's create a 'nodes' data frame
my_nodes <- as.data.frame(rbind(
  cbind(nodename = org, type = "Organization"),
  cbind(unique(person), "People"),
  cbind("Parent", "Parent org")))

# Let's add an ID column to the nodes data frame
my_nodes <- rowid_to_column(my_nodes, "ID")

# Let's create a data frame with al possible edges 
# (i.e., connecting organizations to people and organizations to the parent organization)
my_edges <- data.frame(rbind(
  cbind(ColA = org, ColB = person, type = "Set 1"),
  cbind(org, link, "Set 2")))

my_edges <- subset(my_edges, ColB != 0) 
my_edges$ColB[my_edges$ColB == 1] <- "Parent"

# Let's set up the network object using edges and nodes
my_network <- network(my_edges,
                      vertex.attr = my_nodes,
                      matrix.type = "edgelist",
                      ignore.eval = FALSE)

Notice that we created a column type to categorize both nodes and edges. We can use type to change node/edge color, size, shape, etc. when visualizing the.network.

Here is an example using package igraph . First, we convert the network object into an igraph object.

library(igraph)
library(intergraph)

my_netgraph <- asIgraph(my_network)

The attributes of your nodes can be assessed using V(my.netgraph)$attribute_name . For instance, let's look at the type of nodes in your.network that we defined earlier:

> V(my_netgraph)$type
[1] "Organization" "Organization" "Organization" "Organization" "Organization" "Organization"
[7] "Organization" "Organization" "Organization" "Organization" "People"       "People"      
[13] "People"       "People"       "People"       "People"       "People"       "Parent org"

Now let's color those nodes according to type . To do that, we will create a new attribute, $color . Each $color should correspond to a different $type :

V(my_netgraph)[V(my_netgraph)$type == "People"]$color <- "green"
V(my_netgraph)[V(my_netgraph)$type == "Organization"]$color <- "red"
V(my_netgraph)[V(my_netgraph)$type == "Parent org"]$color <- "yellow"

plot(my_netgraph)

This is what the.network looks like now:

在此处输入图像描述

Now let's change the $shape of the nodes according to attribute $type :

V(my_netgraph)[V(my_netgraph)$type == "People"]$shape <- "circle"
V(my_netgraph)[V(my_netgraph)$type == "Organization"]$shape <- "square"
V(my_netgraph)[V(my_netgraph)$type == "Parent org"]$shape <- "rectangle" 

plot(my_netgraph)

在此处输入图像描述

We can change other attributes of our igraph object using the functions below:

E(my_netgraph) # changes he edges of the "net" object
V(my_netgraph) # changes the vertices of the "net" object
E(my_netgraph)$type # changes edge attribute "type"
V(my_netgraph)$media # changes the vertex attribute "media"

You can find more details on this iGraph manual (pages 10-11).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM