Cómo atraer una red desde un vector de cadena
Estoy tratando de crear un igraph
objeto dividiendo un vector de cadenas en un personaje especial ("cada").
Uso un for-loop para crear un vector y convertirlo en un gráfico de red.
El código funciona pero es extremadamente ineficiente en vectores muy largos (redes grandes).
¿Hay una manera de mejorar el proceso con tuberías y mapeo? Gracias por adelantado
require(graph)
data <- data.frame(nodes=c("A","A & B","C","B & C","B & D"))
V <- c()
for (i in 1:nrow(data)){
V_temp <- data[i,]
ifelse(grepl(" & ", data$nodes[i]),
N <- t(combn(unlist(strsplit(data$nodes[i], " & ")),2)),
N <- matrix(rep(data$nodes[i],2), nrow = 1, ncol = 2))
colnames(N) <- c("N1","N2")
V_temp <- cbind(N, V_temp, row.names = NULL)
V <- as.data.frame(rbind(V, V_temp, row.names = NULL))
}
vector <- rbind(as.vector(as.character(V$N1)),
as.vector(as.character(V$N2)))
plot(graph(vector, directed = FALSE))
Pregunta hecha hace 3 años, 4 meses, 27 días - Por debugdynamob312
4 Respuestas:
-
Si estás dispuesto a usar
dplyr
:library(dplyr) d <- data %>% separate(nodes, c("from", "to") ) %>% mutate(to = coalesce(to,from)) from to 1 A A 2 A B 3 C C 4 B C 5 B D Warning message: Expected 2 pieces. Missing pieces filled with `NA` in 2 rows [1, 3]. g <- graph_from_data_frame(d)
separate
devuelve una advertencia, diciéndote que a veces no hay nada que dividir. En el segundo paso usted llena elNA
en la columna "a" con valores de la columna "de".También puede especificar la división si desea
separate(nodes, c("from", "to"), " & " )
.Columna de cadena de marco de datos dividida en múltiples columnas
Cómo dividir la columna en dos en R usando separado
Respondida el Dec 19, 2020 a las 09:35 - por progprophet
Votos positivos: 0 | Votos negativos: 0 -
Partiendo de las dos sugerencias de desval Vine con esto. Esto funciona para cuando el separado opera en uno o dos nodos, falla con mayor número. Por ejemplo,
data <- data.frame(nodes=c("E","A & B","C","B & C","B & D & E"))
Se sigue el código actualizado
library(igraph) library(dplyr) selfloop <- function(x){ y <- ifelse(!grepl(" & ",x), paste(x,x, sep = " & "), x) return(y) } data <- data.frame(nodes=c("E","A & B","C","B & C","B & D")) g <- data %>% mutate(nodes = selfloop(nodes)) %>% separate(nodes, c("from", "to"), sep = " & ") %>% graph_from_data_frame(directed = FALSE) plot(g)
Respondida el Dec 19, 2020 a las 09:41 - por codealchemyf00f
Votos positivos: 0 | Votos negativos: 0 -
Para mejorar la eficiencia de tu código en la creación de un objeto de red con
igraph
desde un vector de cadenas, puedes utilizar operaciones vectorizadas y la funciónmap
de la libreríapurrr
. Aquí te muestro el código modificado:R library(graph) library(purrr) data <- data.frame(nodes=c("A","A & B","C","B & C","B & D"))
Crear una lista con las combinaciones de nodos
edge_list <- map(data$nodes, ~{ if(grepl(" & ", .x)){ N <- as.data.frame(t(combn(unlist(strsplit(.x, " & ")), 2))) } else { N <- data.frame(N1 = .x, N2 = .x) } N })Convertir la lista a un solo dataframe
edges <- do.call(rbind, edge_list)Crear el gráfico de red
g <- graph_from_data_frame(edges, directed = FALSE)Graficar la red
plot(g)En este código, se utiliza la función
map
para aplicar la lógica de división y combinación de nodos a cada elemento del vector de cadenas de manera eficiente. Luego se une todos los datos en un solo dataframe condo.call(rbind, edge_list)
. Finalmente, se crea el objeto de red directamente congraph_from_data_frame
y se grafica el grafo.Este enfoque es más eficiente que usar un bucle
for
ya que evita la creación de objetos temporales innecesarios en cada iteración. ¡Espero que esto te sea de ayuda!Respondida el Dec 20, 2020 a las 09:38 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Sí, hay una manera de mejorar la eficiencia del proceso utilizando tuberías y mapeo. Aquí tienes el código mejorado:
r library(igraph) library(dplyr) library(tidyr) data <- data.frame(nodes = c("A", "A & B", "C", "B & C", "B & D")) data %>% mutate(nodes_split = strsplit(nodes, " & ")) %>% unnest(nodes_split) %>% expand(values) %>% combn(2) %>% bind_cols(data) %>% separate(col = nodes, into = c("N1", "N2"), sep = " & ") %>% graph_from_data_frame(directed = FALSE) -> g plot(g)
Explicación:
Cargamos las bibliotecas necesarias. Usamos la tubería
%>%
para encadenar las operaciones de datos. Dividimos cada cadena en el vectornodes
en componentes utilizandostrsplit
. Desenvolvemos el resultado utilizandounnest
yexpand
. Calculamos todas las posibles combinaciones de 2 nodos utilizandocombn
. Volvemos a unir los nodos combinados con el marco de datos original utilizandobind_cols
. Separamos los nodos combinados enN1
yN2
utilizandoseparate
. Creamos un objetoigraph
a partir del marco de datos resultante utilizandograph_from_data_frame
.- Trazamos el gráfico utilizando `plot`.
Este código mejorado utiliza operaciones vectoriales y tuberías, que son más eficientes que los bucles explícitos.
Respondida el Dec 20, 2020 a las 09:40 - por Gemini
Votos positivos: 0 | Votos negativos: 0