varias superponer studio lineas graficos graficas r list merge

studio - superponer graficas en r



Lista de fusiĆ³n con elementos comunes (4)

Aquí hay un enfoque basado en la purrr:

library(purrr) mylist <- list(7, c(10, 11, 12, 211, 446, 469), c(10, 11, 12, 13), c(11, 12, 13, 215), c(15, 16), c(15, 17, 216, 225)) result <- mylist %>% # check whether any numbers of an element are in any of the elements map(~map_lgl(mylist, compose(any, `%in%`), .x)) %>% unique() %>% # drop duplicated groups map(~reduce(mylist[.x], union)) # subset lst by group and collapse subgroups str(result) #> List of 3 #> $ : num 7 #> $ : num [1:8] 10 11 12 211 446 469 13 215 #> $ : num [1:5] 15 16 17 216 225

La lógica aquí es similar a la respuesta de Ronak; Me parece más fácil de leer. Si lo desea, puede escribir la última línea como map(~unique(flatten_dbl(mylist[.x]))) o dividirla en map(~mylist[.x]) %>% simplify_all() %>% map(unique) .

Para los índices de qué elemento se agrega a qué grupo, simplemente llame a los elementos utilizados para el subconjunto:

mylist %>% map(~map_lgl(mylist, compose(any, `%in%`), .x)) %>% unique() %>% map(which) %>% str() #> List of 3 #> $ : int 1 #> $ : int [1:3] 2 3 4 #> $ : int [1:2] 5 6

Una lógica alternativa para todo es hacer que la lista sea anidada en lugar de las llamadas, lo que significa que la auto-unión está por adelantado (con cross2 ), no hay subconjuntos más tarde, y la mayoría de las funciones son solo operaciones programadas:

mylist %>% map(cross2, mylist) %>% modify_depth(2, reduce, ~if(length(intersect(.x, .y)) > 0) sort(union(.x, .y))) %>% map(reduce, union) %>% unique()

o usando el parámetro .filter cross2 ,

mylist %>% map(cross2, mylist, ~length(intersect(.x, .y)) == 0) %>% map(compose(sort, unique, unlist)) %>% unique()

que podría condensarse para

mylist %>% map(function(element) sort(unique(unlist(cross2(element, mylist, ~length(intersect(.x, .y)) == 0))))) %>% unique()

Sin embargo, estos enfoques no arrojan grupos duplicados hasta el final, por lo que es probable que sean menos eficientes.

Tengo una lista

[[1]] [1] 7 [[2]] [1] 10 11 12 211 446 469 [[3]] [1] 10 11 12 13 [[4]] [1] 11 12 13 215 [[5]] [1] 15 16 [[6]] [1] 15 17 216 225

Quiero fusionar secciones de lista que tienen elementos comunes e indexar qué sectores de lista se han fusionado. Mi resultado deseado está abajo.

$`1` [1] 7 $`2`, `3`, `4` [1] 10 11 12 13 211 215 446 469 $`5`,`6` [1] 15 16 17 216 225

(He puesto los índices de división de listas originales como nuevos nombres de lista, pero cualquier forma de salida está bien).

Datos reproducibles:

mylist <- list(7, c(10, 11, 12, 211, 446, 469), c(10, 11, 12, 13), c(11, 12, 13, 215), c(15, 16), c(15, 17, 216, 225))


Aquí hay otro enfoque que usa paquetes "Matrix" e "igraph".

Primero, necesitamos extraer la información de qué elementos están conectados. Usar matrices dispersas puede, potencialmente, ahorrar mucho uso de memoria:

library(Matrix) i = rep(1:length(mylist), lengths(mylist)) j = factor(unlist(mylist)) tab = sparseMatrix(i = i, j = as.integer(j), x = TRUE, dimnames = list(NULL, levels(j))) #as.matrix(tab) ## just to print colnames # 7 10 11 12 13 15 16 17 211 215 216 225 446 469 #[1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE #[2,] FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE #[3,] FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE #[4,] FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE #[5,] FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE #[6,] FALSE FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE TRUE TRUE FALSE FALSE

Encuentre si cada elemento está conectado entre sí:

connects = tcrossprod(tab, boolArith = TRUE) #connects #6 x 6 sparse Matrix of class "lsCMatrix" # #[1,] | . . . . . #[2,] . | | | . . #[3,] . | | | . . #[4,] . | | | . . #[5,] . . . . | | #[6,] . . . . | |

Luego, usando gráficos, podemos agrupar los índices de "mylist":

library(igraph) # ''graph_from_adjacency_matrix'' seems to not work with the "connects" object directly. # An alternative to coercing "connects" here would be to build it as ''tcrossprod(tab) > 0'' group = clusters(graph_from_adjacency_matrix(as(connects, "lsCMatrix")))$membership #group #[1] 1 2 2 2 3 3

Y, finalmente, concatenar:

tapply(mylist, group, function(x) sort(unique(unlist(x)))) #$`1` #[1] 7 # #$`2` #[1] 10 11 12 13 211 215 446 469 # #$`3` #[1] 15 16 17 216 225 tapply(1:length(mylist), group, toString) # 1 2 3 # "1" "2, 3, 4" "5, 6"


Aquí hay una función recursiva que realiza la tarea (aunque ahora genera un montón de advertencias).

mylist <- list(7, c(10, 11, 12, 211, 446, 469), c(10, 11, 12, 13), c(11, 12, 13, 215), c(15, 16), c(15, 17, 216, 225)) commonElements = function(l,o=list(l[[1]])){ if(length(l) == 0){return(o)} match = which(unlist(lapply(lapply(o,intersect,l[[1]]),any))) if(length(match) == 0) o[[length(o)+1]] = l[[1]] if(length(match) == 1) o[[match]] = unique(c(o[[match]],l[[1]])) if(length(match) > 1){ o[[match[1]]] = unique(unlist(o[match])) p[rev(match)[-1]] = NULL } l[[1]] = NULL commonElements(l,o) } commonElements(mylist)

Básicamente, pase en una lista y crea una instancia de la salida, o , con el primer elemento de l . Luego, comprueba cada valor de l contra cada grupo en o , si no coincide con nada, crea un nuevo elemento en o , si coincide con uno, conserva el conjunto único y si coincide con más de 1, concatenar los grupos en o y soltar los extras .


No estoy contento con la solución, pero esto creo que da la respuesta. Todavía hay un alcance de mejora:

unique(sapply(lst, function(x) unique(unlist(lst[sapply(lst, function(y) any(x %in% y))])))) #[[1]] #[1] 7 #[[2]] #[1] 10 11 12 211 446 469 13 215 #[[3]] #[1] 15 16 17 216 225

Esto es básicamente un bucle doble para verificar si alguno de los elementos de la lista está presente en cualquier otra lista. Si encuentra algún elemento de ese tipo, combínelos tomando valores unique de ellos.

datos

lst <- list(7, c(10 ,11 ,12, 211, 446, 469), c(10, 11, 12, 13),c(11 ,12, 13 ,215), c(15, 16), c(15, 17 ,216 ,225))