использование lapply для создания нового списка фреймов данных, обобщающего сетевой анализ

#r #list #lapply #network-analysis

#r #Список #lapply #network-анализ

Вопрос:

У меня есть список данных, который содержит сети в виде фреймов данных. Что я хотел бы сделать, так это выполнить функцию, которая вычисляет несколько сетевых свойств и сохраняет их в новом списке фреймов данных

например:

 #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)
  

Затем я создал функцию, которая успешно вычисляет сетевые свойства и связывает их с новым фреймом данных

 ##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)
}
  

Эта функция работает, когда я прошу ее вычислить сетевые свойства для одного из фреймов данных по отдельности, например:

 network.A <- network.summary(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
  

Мне нужен список, содержащий фреймы данных, подобные этому. однако, когда я пытаюсь выполнить эту функцию в этом списке, кажется, что создается только пустой список без сообщения об ошибке, используя следующий код

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

Я видел несколько сообщений по другим вопросам, которые близки к этому, но, похоже, не понимаю, почему это не работает и что мне нужно добавить в мой код.

Ответ №1:

Идея использования apply хороша! Однако вы ошиблись в своем первом аргументе. my_list это безымянный список, что означает, что names(my_list) он вернется NULL . Есть несколько способов решить эту проблему:

  1. Назовите свой список, например, 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. Измените аргументы в вашем lapply() вызове
 (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
  

Действительно, если вы примените a list к lapply() , то он применит функцию, которую вы предоставляете, к каждому элементу в вашем списке. Это также означает, что вам не нужно добавлять my_list[[x]] к предоставленной вами функции, поскольку предоставленная функция уже применяется к каждому элементу в списке, my_list[[x] т. Е. к существующему. Следовательно, вы можете просто записать x network.summary() .