Meta-análise R (2): Analisando Pacotes R como indivíduos em uma rede social

O objetivo deste segundo post da série sobre meta-análise de pacotes R é testar a utilização de diferentes pacotes voltados para a análise de redes sociais (SNA). Existem dezenas de opções disponíveis para se fazer esta análise e os usados neste post são:

Da Wikipedia:

As Redes Sociais consistem em estruturas que representam pessoas ou organizações (atores) e as relações entre si. A Análise de Redes Sociais perceciona as relações sociais em termos da Teoria de Redes. Permite estudar, através da identificação dos atores e suas ligações, as relações entre os mesmos de forma a poder identificar as formas de interação entre si, contribuindo para o conhecimento sobre a rede social e o seu desenvolvimento. A Análise de Redes Sociais (ARS) permite representar as redes sociais através da representação dos nós e das ligações entre eles. Os nós da rede social representam os atores dessa rede (indivíduos ou organizações). As ligações representam as relações entre os atores componentes da rede representada.

Não sou nem de longe um especialista nesse tema, mas tenho uma grande curiosidade sobre ele e já li alguns artigos e documentações de pacotes R sobre SNA.

suppressMessages(library(igraph))
suppressMessages(library(miniCRAN))
suppressMessages(library(magrittr))
suppressMessages(library(keyplayer))
suppressMessages(library(dplyr))
library(feather)
suppressMessages(library(visNetwork))
library(knitr)
suppressMessages(library(DT))

#devtools::install_github("wch/webshot")
#webshot::install_phantomjs()

Para este post, vou usar, arbitrariamente, os 50 pacotes R mais baixados, que são:

df_pkgs <- read_feather("/home/sillas/R/Projetos/PaixaoPorDados/sillasgonzaga.github.io/data/df_pkgs.feather")
df_pkgs %<>% top_n(50, wt = downloads)
(list_pkgs <- df_pkgs$package)
##  [1] "RcppArmadillo" "Rcpp"          "ggplot2"       "digest"       
##  [5] "stringr"       "plyr"          "stringi"       "magrittr"     
##  [9] "scales"        "reshape2"      "RColorBrewer"  "gtable"       
## [13] "munsell"       "rgl"           "colorspace"    "labeling"     
## [17] "dichromat"     "DBI"           "jsonlite"      "R6"           
## [21] "BH"            "zoo"           "mime"          "curl"         
## [25] "nlme"          "mixOmics"      "openssl"       "bitops"       
## [29] "devtools"      "dplyr"         "car"           "rJava"        
## [33] "knitr"         "quantreg"      "evaluate"      "survival"     
## [37] "httr"          "htmltools"     "data.table"    "lme4"         
## [41] "formatR"       "RCurl"         "chron"         "yaml"         
## [45] "foreach"       "caTools"       "Hmisc"         "xtable"       
## [49] "highr"         "rmarkdown"
g <- makeDepGraph(list_pkgs, suggests = FALSE)

plot(g, main = "")

plot.igraph(g, vertex.size=10, layout = layout_with_fr(g)) 

O número de pacotes selecionados para a análise dificultou a leitura da visualização do grafo, mas servirá para analisar diferentes métricas associadas à ARS.

Como homenagem ao Hadley Wickham, os pacotes pertencentes ao Hadleyverse (lista de pacotes R criados ou que tiveram contribuição de Wickham) serão destacados no grafo. O código abaixo foi tirado deste ótimo artigo sobre o Hadleyverse.

# baixar lista de pacotes disponíveis no CRAN
#download.file("http://cran.r-project.org/web/packages/packages.rds", "packages.rds") cerca de 3 MB
rds <- readRDS(file="packages.rds")
data <- as.data.frame(rds, stringsAsFactors = FALSE)

# Limpar os dados
data <- data[,!duplicated(names(data))]
names(data) <- gsub(" ","_", names(data))
names(data) <- gsub("/","_", names(data))
names(data) <- gsub("@","_", names(data))

# Filtrar pacotes do Hadley
hadley <- data %>%
  filter(grepl("Hadley Wickham|Hadley\nWickham", Author)) %>%
  select(Package, Author, Depends, Imports, Suggests, LinkingTo, Enhances)

#Adicionar atributo de grupo aos vértices do grafo
V(g)$group <- ifelse(V(g)$name %in% hadley$Package, "hadleyverse", "no_hadley")

Como estou escrevendo para um blog e não para um artigo, acredito que um grafo interativo seja melhor do que um estático. Para plotar uma rede interativa, existe o excelente pacote visNetwork. Use o mouse para controlar o grafo abaixo, seja arrastando os vértices ou dando zoom.

visIgraph(g, physics = TRUE, smooth = TRUE, type = "full", randomSeed = 123) %>%
  visOptions(width = "100%", height = "90%",
             highlightNearest = list(enabled = TRUE, degree = 1, hover = TRUE),
             nodesIdSelection = list(enabled = TRUE)) %>%
  visInteraction(hover = TRUE, navigationButtons = TRUE) %>%
  visGroups()

Outra atividade comumente feita em SNA é calcular diversas métricas de rede. As principais são:

Fonte.

Todas as métricas acima podem ser calculadas com o pacote igraph.

indegree <- degree(g, mode = "in")
outdegree <- degree(g, mode = "out")
incloseness <- closeness(g, mode = "in") %>% round(6)
outcloseness <- closeness(g, mode = "out") %>% round(6)
betweenness <- betweenness(g) %>% round(1)
eigenvector <- eigen_centrality(g, directed = FALSE) %$% vector %>% round(3)

df_sna <- data.frame(indegree, outdegree, incloseness, outcloseness, betweenness, eigenvector)
# criar tabela interativa com pacote DT
datatable(df_sna)

Conclusões:

Com a tabela acima, podemos ter alguns aprendizados:
- Os pacotes de maior indegree são NMF e Hmisc, que curiosamente têm outdegree baixo. Isso significa que eles importam muitos pacotes mas não são importados por muitos;
- O pacote Rcpp tem os maiores níveis de outdegree e autovetor, o que mostra sua importância para o desenvolvimento de pacotes R.
- O fato do ggplot2 apresentar o maior betweenness é curioso. Deixo o significado disso para interpretação do leitor.