## Two-mode Data Structure

tnet » Software » Two-mode Data Structure Two-mode networks (also known as affiliation or bipartite networks) are a particular type of networks with two sets of nodes and ties are only established between nodes belonging to different sets. The network diagram illustrates a weighted two-mode network where the colour represent the node set to which a node belongs. One of the first two-mode datasets to be analysed was the Davis Southern Club Women dataset (Davis et al., 1941), which recorded the attendance of a group of women (node set 1) to a series of events (set 2). A woman would be linked to an event if she attended it. Another type of two-mode dataset that has become popular in recent years is scientific collaboration networks. In this type of networks, a tie is established between a scientist (node set 1) and a paper (node set 2) if the scientist authored that paper (e.g., Newman, 2001).

Similarly to one-mode networks, two-mode networks are represented by edgelists. This is due to the fact that most two-mode networks are sparse (i.e., the number of ties is much smaller than the number of nodes squared). There are two formats used in tnet to represent two-mode networks depending on whether they are binary or weighted. This system was adopted to lessen confusion as most two-mode networks are binary and weighted two-mode networks can be confused with weighted one-mode networks.

Binary Two-mode Networks

Binary two-mode networks should be represented as a two-column data frame where the first column contain the primary or top nodes and the second column contains the secondary or bottom nodes. If the blue nodes are the primary nodes in the diagram above, the binary network should be represented as follows in R:

```      [,1] [,2]
[1,]    1    1
[2,]    1    2
[3,]    2    1
[4,]    2    2
[5,]    2    3
[6,]    2    4
[7,]    2    5
[8,]    3    2
[9,]    4    3
[10,]    5    4
[11,]    5    5
[12,]    5    6
[13,]    6    6
```

Weighted Two-mode Networks

Weighted two-mode networks are similar to binary two-mode networks, but have an additional third column containing tie weights.

The weighted network about should be represented as follows in R:

```      [,1] [,2] [,3]
[1,]    1    1    4
[2,]    1    2    2
[3,]    2    1    2
[4,]    2    2    1
[5,]    2    3    4
[6,]    2    4    3
[7,]    2    5    2
[8,]    3    2    5
[9,]    4    3    6
[10,]    5    4    2
[11,]    5    5    4
[12,]    5    6    1
[13,]    6    6    1
```

Note: As weighted two-mode network can be confused with weighted one-mode networks, it is important to run as.tnet(net, type=”weighted two-mode tnet”) before using any analysis functions. See below.

The most common way of loading a network is to read a text file with the network. The `read.table`-function is the standard method for reading text files. This function works by giving it a filename or link, and a character for separating the values into columns (e.g., a tab). It is important to not just read, but also assign the read file to an object. To illustrate this procedure, the binary and weighted versions of the above network can be loaded into the objects `binary.net` and `weighted.net` using these commands (note that these files are on the web, and hence, the link instead of a filename).

```# Read the binarynetwork

```

Ensure that the network conforms to the tnet standard

To ensure that the network conforms to the tnet standard, the `as.tnet`-function can be used. This function is run automatically by the functions if it has not been run on the network manually. This function takes two parameters: the network and a character string specifying the type of network. If the type parameter is not set, an object will be assumed to be a binary two-mode edgelist if it has two columns or if it is a non-square matrix with more than 4 nodes and only 0 and 1 values. It will not be assumed to be a weighted two-mode edgelist if it has three columns (however, it will if it is a non-square matrix with more than 4 nodes and not only 0 and 1 values). Below is the code for testing the weighted network above.

```# Load tnet
library(tnet)

# Check that it confirms to the tnet standard for weighted one-mode networks
weighted.net <- as.tnet(weighted.net, type="weighted two-mode tnet")
```

To allow for a comparison between weighted and binary network measures, the `dichotomise_tm`-function creates a binary network from a weighted one. It does so by removing the ties in a weighted edgelist that fall below a certain cut-off and sets the weight to 1 for the remaining ones.

If you use tnet, please cite: Opsahl, T., 2009. Structure and Evolution of Weighted Networks. University of London (Queen Mary College), London, UK, pp. 104-122. Available at https://toreopsahl.com/publications/thesis/.

• 1. simonegabbriellini  |  February 19, 2014 at 9:47 am

Dear Tore,

I am trying to use tnet to work on a two-mode weighted dataset, but I am having troubles to load my data… I read the csv and do as.tnet() without problems, but when I call projecting_tm() I get:

Warning messages:
1: In cbind(p = as.numeric(row.names(np)), np = np) :
si è prodotto un NA per coercizione
2: In Ops.factor(net[, 1], net[, 2]) : not meaningful for factors
4: In as.tnet(net1, type = “weighted one-mode tnet”) :
The network might be undirected. If this is the case, each tie should be mention twice. The symmetrise-function can be used to include reverse version of each tie.
5: In min(c(net[, “i”], net[, “j”])) :
no non-missing arguments to min; returning Inf

Is there any hint you can give me to clear this issue I have?

Best regards,
Simone

• 2. Tore Opsahl  |  February 19, 2014 at 1:10 pm

Hi Simone,

The projecting_tm-function works on two-mode networks. Have you run as.tnet(networkObject, type=’binary two-mode tnet’)?

If you have any issues, email me your code and data. Then I’ll have a look.

Best,
Tore

• 3. Sebastian  |  April 18, 2018 at 3:23 pm

Hi Tore, thank you for your work – tnet is great. Did you manage to figure out @simonegabbriellini’s problem?

I have a similar issue. I have a list of data frames that each contain a weighted two-mode network with three columns: “actor”, “event”, “weight”. When I use projecting_tm, it works fine and the command projects the (undirected) weighted two-mode network onto a weighted one-mode network for variable “actor”. I can now compute the closeness_w and betweenness_w.

However, I also want to compute these indicators for the “event”s. This means I have to project the (undirected) weighted two-mode network onto a weighted one-mode network for variable “event”. I have not figured out how to do this within the projecting_tm command, so I simply re-arranged the colums to have a list of data frames that each contain a weighted two-mode network with three columns: “event”, “actor”, “weight”.

When I use projecting_tm, I get the following error messages (similar to @simonegabbriellini’s). I did run the as.tnet, type=”weighted two-mode tnet” commands.

Warning messages:
1: In as.tnet(net1, type = “weighted one-mode tnet”) :
The network might be undirected. If this is the case, each tie should be mention twice. The symmetrise-function can be used to include reverse version of each tie.
2: In min(c(net[, “i”], net[, “j”])) :
no non-missing arguments to min; returning Inf
3: In as.tnet(net1, type = “weighted one-mode tnet”) :
The network might be undirected. If this is the case, each tie should be mention twice. The symmetrise-function can be used to include reverse version of each tie.
4: In min(c(net[, “i”], net[, “j”])) :
no non-missing arguments to min; returning Inf
5: In as.tnet(net1, type = “weighted one-mode tnet”) :
The network might be undirected. If this is the case, each tie should be mention twice. The symmetrise-function can be used to include reverse version of each tie.
6: In min(c(net[, “i”], net[, “j”])) :
no non-missing arguments to min; returning Inf
7: In as.tnet(net1, type = “weighted one-mode tnet”) :
The network might be undirected. If this is the case, each tie should be mention twice. The symmetrise-function can be used to include reverse version of each tie.
8: In min(c(net[, “i”], net[, “j”])) :
no non-missing arguments to min; returning Inf

• 4. Tore Opsahl  |  April 19, 2018 at 12:54 am

Hi Sebastian,

The first thing to do with weighted two-mode networks is to use the as.tnet-function on them. This is because three column edgelists are assumed to be weighted one-mode networks. Try the code below first, and if you have any issues, send me an email.

Good luck!
Tore

```# Load tnet
library(tnet)

# Create a list object with two of the dataset in tnet

# Explicitly set network type
nets2m <- lapply(nets2m, function(a) as.tnet(net = a, type="weighted two-mode tnet"))

# Project to one-mode among primary nodes
nets1mP <- lapply(nets2m, function(a) projecting_tm(a, method="sum"))

# Project to one-mode among secondary nodes
nets2mS <- lapply(nets2m, function(a) a[,c(2,1,3)])
nets1mS <- lapply(nets2mS, function(a) projecting_tm(a, method="sum"))
```
• 5. Sebastian  |  April 19, 2018 at 3:45 am

Hi Tore, thank you for your quick response. I ran the code like this on my data and it did not help. However, I think I now know what went wrong. I have a relatively long list of data frames that correspond to yearly data. I investigated these individually and it turns out that in four years (data frames), there was only one event that took place. I guess this is why R was able to project to an one-mode among primary nodes (actors) but not to an one-mode among secondary nodes (events).

Talking about years… As I understand, tnet can work with either weighted two-mode networks or longitudinal networks. Do you know if there is work going on to analyse longitudinal weighted two-mode networks? On page 3 of the tnet package documentation (https://cran.r-project.org/web/packages/tnet/tnet.pdf), paragraph 3 on timed data seems to go into this direction but I am not whether it is two-mode.

• 6. Tore Opsahl  |  April 22, 2018 at 8:13 pm

Hi Sebastian,

I started with on longitudinal two-mode networks with Antoine Vernet. Reach out to him as he carried this line for work forward.

Best,
Tore

• 7. Sebastian  |  August 10, 2018 at 3:18 am

Hi Tore,
I would like to ask you another question on tnet. Do I understand correctly that degree_tm can be used to calculate degree centrality in a (not weighted) two-mode network and degree_w can be used to calculate degree centrality in a (not two-mode) weighted network?
If I have a weighted two-mode network, would I simply set the network type to type=”weighted two-mode tnet” and then use the degree_w command? This would be great since I could then use the alpha parameter, which isn’t available in degree_tm.
Many thanks and best,
Sebastian

• 8. Tore Opsahl  |  August 10, 2018 at 7:15 am

Hi Sebastian,

The degree_tm-function calculates the node strength of two mode networks. There isn’t an alpha parameter, but you can hack this by loading the network as a one mode network (make sure that the node ids do not overlap to avoid self loops).

Best,
Tore

• 9. Sebastian  |  August 11, 2018 at 5:46 am

Hi Tore,

thanks again for your quick response – this makes sense. Have you had a chance to work on the optimal value of alpha as indicated in your Social Networks (2010) paper?

Best,
Sebastian

• 10. Tore Opsahl  |  August 16, 2018 at 9:19 pm

Hi Sebastian,

After leaving academia, it has been hard to find the time to do this research. Have a look at comment #40 on this page: https://toreopsahl.com/2010/04/21/article-node-centrality-in-weighted-networks-generalizing-degree-and-shortest-paths/ for a suggestion on how to set up this problem.

Let me know what you find!

Best,
Tore