Stavrum
Stavrum

Reputation: 71

using lapply to create a new list of dataframes that summarises network analysis

I have a list of data which contains networks in the form of dataframes. What I would like to do is perform a function which calculates multiple network properties and stores them in a new list of dataframes

for example:

#Create example matrices for network analysis
A = matrix( c( NA, 1, 0, 3, 1, NA, 4, 3, 1, 0, NA, 3, 1, 1, 0, NA ), nrow = 4, ncol = 4)
B = matrix( c( NA, 2, 3, 0, 4, NA, 3, 1, 0, 3, NA, 2, 0, 2, 1, NA ), nrow = 4, ncol = 4)
C = matrix( c( NA, 0, 0, 1, 2, NA, 0, 5, 1, 2, NA, 0, 3, 3, 0, NA ), nrow = 4, ncol = 4)

#transform into dataframes as this is the form they are in within my list
A <- as.data.frame(A)
B <- as.data.frame(B)
C <- as.data.frame(C)

colnames(A) <- letters[1:4]
colnames(B) <- letters[1:4]
colnames(C) <- letters[1:4]

#create list of matrices
my_list <- list(A, B, C)

#install igraph for network analysis
install.packages("igraph")
library(igraph)

I then have created a function which is successful in calculating network properties and binds them into a new dataframe

##create function which summarises network properties and puts them in a data frame
network.summary <- function(data) {
  data <- as.matrix(data)
  g <- graph_from_adjacency_matrix(data, mode = c("directed"), weighted = TRUE,
                                   add.colnames = NULL, add.rownames = NA)
  centrality <- degree(g, mode='all')
  closeness <- closeness(g, mode='all')
  betweenness <- betweenness(g, directed = T,)
  network.properties <- rbind(centrality, closeness, betweenness)
}

This function works when I ask it to compute network properties on one of the dataframes individually for example:

network.A <- network.summary(A)

results in

                    a    b         c   d
centrality  7.0000000 7.00 5.0000000 7.0
closeness   0.3333333 0.25 0.1666667 0.2
betweenness 1.0000000 2.00 0.0000000 0.0

What I want is a list containing dataframes like this one. however when I try to perform this function across this list it only seems to create a blank list with no error message using the following code

network.properties <- lapply(names(my_list), function(x) network.summary(my_list[[x]]))

I have seen a few posts on other questions which are close to this, but cant seem to understand why this isn't working and what I need to add to my code.

Upvotes: 0

Views: 256

Answers (1)

PLY
PLY

Reputation: 571

The idea of using apply is good! However, you were wrong with your first argument. my_list is an unnamed list, which means that names(my_list) will return NULL. There are several ways to solve this:

  1. Name your list, e.g., my_list = c(a = A, b = B, c = C)
my_list <- list(a = A, b = B, c = C)
(network.properties <- lapply(names(my_list), function(x) network.summary(my_list[[x]])))
#> [[1]]
#>                     a    b         c   d
#> centrality  7.0000000 7.00 5.0000000 7.0
#> closeness   0.3333333 0.25 0.1666667 0.2
#> betweenness 1.0000000 2.00 0.0000000 0.0
#> 
#> [[2]]
#>                     a         b         c         d
#> centrality  5.0000000 8.0000000 7.0000000 6.0000000
#> closeness   0.1111111 0.1428571 0.1428571 0.1666667
#> betweenness 0.0000000 3.0000000 0.0000000 1.0000000
#> 
#> [[3]]
#>                a         b   c         d
#> centrality  6.00 6.0000000 4.0 6.0000000
#> closeness   0.25 0.1428571 0.2 0.1666667
#> betweenness 2.00 0.0000000 0.0 1.0000000
  1. Change arguments in your lapply() call
(network.properties <- lapply(my_list, function(x) network.summary(x)))
#> $a
#>                     a    b         c   d
#> centrality  7.0000000 7.00 5.0000000 7.0
#> closeness   0.3333333 0.25 0.1666667 0.2
#> betweenness 1.0000000 2.00 0.0000000 0.0
#> 
#> $b
#>                     a         b         c         d
#> centrality  5.0000000 8.0000000 7.0000000 6.0000000
#> closeness   0.1111111 0.1428571 0.1428571 0.1666667
#> betweenness 0.0000000 3.0000000 0.0000000 1.0000000
#> 
#> $c
#>                a         b   c         d
#> centrality  6.00 6.0000000 4.0 6.0000000
#> closeness   0.25 0.1428571 0.2 0.1666667
#> betweenness 2.00 0.0000000 0.0 1.0000000

Indeed, if you apply a list to lapply(), then it will apply the function you provide to every element in your list. This also implies that you do not need to add my_list[[x]] to your provided function, as the provided function is already applied on every element in the list, i.e. my_list[[x] that exists. Hence you can simply write x in network.summary().

Upvotes: 1

Related Questions