#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
. Есть несколько способов решить эту проблему:
- Назовите свой список, например,
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
- Измените аргументы в вашем
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()
.