ver tabla presentacion nuevo mapas mapa herramientas fuente establecer definicion datos data crear contenido como barra arcmap r list dataframe

tabla - R-lista al marco de datos



tabla contenido arcgis (17)

Tengo una lista anidada de datos. Su longitud es 132 y cada elemento es una lista de longitud 20. ¿Hay una forma rápida de convertir esta estructura en un marco de datos que tenga 132 filas y 20 columnas de datos?

Aquí hay algunos datos de muestra para trabajar con:

l <- replicate( 132, list(sample(letters, 20)), simplify = FALSE )


test1 <- lista (c (a = ''a'', b = ''b'', c = ''c''), c (a = ''d'', b = ''e'', ​​c = ''f'')) as.data .frame (test1) abc 1 abc 2 def

test2 <- lista (c (''a'', ''b'', ''c''), c (a = ''d'', b = ''e'', ​​c = ''f''))

as.data.frame (test2) abc 1 abc 2 def

test3 <- lista (''Fila1'' = c (a = ''a'', b = ''b'', c = ''c''), ''Fila2'' = c (a = ''d'', var2 = ''e'', ​​var3 = ''F''))

as.data.frame (test3) abc var2 var3 Fila1 abc
Fila2 def


A veces sus datos pueden ser una lista de listas de vectores de la misma longitud.

lolov = list(list(c(1,2,3),c(4,5,6)), list(c(7,8,9),c(10,11,12),c(13,14,15)) )

(Los vectores internos también podrían ser listas, pero estoy simplificando para que sea más fácil de leer).

Entonces puedes hacer la siguiente modificación. Recuerda que puedes anular un nivel a la vez:

lov = unlist(lolov, recursive = FALSE ) > lov [[1]] [1] 1 2 3 [[2]] [1] 4 5 6 [[3]] [1] 7 8 9 [[4]] [1] 10 11 12 [[5]] [1] 13 14 15

Ahora usa tu método favorito mencionado en las otras respuestas:

library(plyr) >ldply(lov) V1 V2 V3 1 1 2 3 2 4 5 6 3 7 8 9 4 10 11 12 5 13 14 15


Con rbind

do.call(rbind.data.frame, your_list)

Edición: la versión anterior devuelve data.frame de la list en lugar de vectores (como @IanSudbery señaló en los comentarios).


Dependiendo de la estructura de sus listas, hay algunas opciones tidyverse que funcionan bien con listas de longitud desigual:

l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3) , b = list(var.1 = 4, var.2 = 5) , c = list(var.1 = 7, var.3 = 9) , d = list(var.1 = 10, var.2 = 11, var.3 = NA)) df <- dplyr::bind_rows(l) df <- purrr::map_df(l, dplyr::bind_rows) df <- purrr::map_df(l, ~.x) # all create the same data frame: # A tibble: 4 x 3 var.1 var.2 var.3 <dbl> <dbl> <dbl> 1 1 2 3 2 4 5 NA 3 7 NA 9 4 10 11 NA

También puedes mezclar vectores y marcos de datos:

library(dplyr) bind_rows( list(a = 1, b = 2), data_frame(a = 3:4, b = 5:6), c(a = 7) ) # A tibble: 4 x 2 a b <dbl> <dbl> 1 1 2 2 3 5 3 4 6 4 7 NA


El paquete data.table tiene la función rbindlist que es una implementación ultrarrápida de do.call(rbind, list(...)) .

Puede tomar una lista de lists , data.frames o data.tables como entrada.

library(data.table) ll <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3) , b = list(var.1 = 4, var.2 = 5, var.3 = 6) , c = list(var.1 = 7, var.2 = 8, var.3 = 9) , d = list(var.1 = 10, var.2 = 11, var.3 = 12) ) DT <- rbindlist(ll)

Esto devuelve una data.table de data.frame .

Si realmente desea volver a convertir a un data.frame use as.data.frame(DT)


El paquete tibble tiene una función enframe() que resuelve este problema al coaccionar objetos de list anidadas en objetos anidados tibble (marco de datos "ordenado"). Aquí hay un breve ejemplo de R para Data Science :

x <- list( a = 1:5, b = 3:4, c = 5:6 ) df <- enframe(x) df #> # A tibble: 3 × 2 #> name value #> <chr> <list> #> 1 a <int [5]> #> 2 b <int [2]> #> 3 c <int [2]>

Como tiene varios nidos en su lista, l , puede usar unlist(recursive = FALSE) para eliminar los anidamientos innecesarios para obtener una sola lista jerárquica y luego pasar a enframe() . Uso tidyr::unnest() para anular la salida en un marco de datos "tidy" de un solo nivel, que tiene sus dos columnas (una para el name del grupo y otra para las observaciones con el value los grupos). Si desea que las columnas se add_column() , puede agregar una columna usando add_column() que simplemente repite el orden de los valores 132 veces. Entonces solo se spread() los valores.


library(tidyverse) l <- replicate( 132, list(sample(letters, 20)), simplify = FALSE ) l_tib <- l %>% unlist(recursive = FALSE) %>% enframe() %>% unnest() l_tib #> # A tibble: 2,640 x 2 #> name value #> <int> <chr> #> 1 1 d #> 2 1 z #> 3 1 l #> 4 1 b #> 5 1 i #> 6 1 j #> 7 1 g #> 8 1 w #> 9 1 r #> 10 1 p #> # ... with 2,630 more rows l_tib_spread <- l_tib %>% add_column(index = rep(1:20, 132)) %>% spread(key = index, value = value) l_tib_spread #> # A tibble: 132 x 21 #> name `1` `2` `3` `4` `5` `6` `7` `8` `9` `10` `11` #> * <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> #> 1 1 d z l b i j g w r p y #> 2 2 w s h r i k d u a f j #> 3 3 r v q s m u j p f a i #> 4 4 o y x n p i f m h l t #> 5 5 p w v d k a l r j q n #> 6 6 i k w o c n m b v e q #> 7 7 c d m i u o e z v g p #> 8 8 f s e o p n k x c z h #> 9 9 d g o h x i c y t f j #> 10 10 y r f k d o b u i x s #> # ... with 122 more rows, and 9 more variables: `12` <chr>, `13` <chr>, #> # `14` <chr>, `15` <chr>, `16` <chr>, `17` <chr>, `18` <chr>, #> # `19` <chr>, `20` <chr>


Este método utiliza un paquete tidyverse ( purrr ).

La lista:

x <- as.list(mtcars)

Convertirlo en un marco de datos (un tibble más específicamente):

library(purrr) map_df(x, ~.x)


Esto es lo que finalmente me funcionó:

do.call("rbind", lapply(S1, as.data.frame))


Extenderse en la respuesta de @ Marek: si quiere evitar que las cadenas se conviertan en factores y eficiencia no es una preocupación intentar

{ "2015": { "spain": {"population": 43, "GNP": 9}, "sweden": {"population": 7, "GNP": 6}}, "2016": { "spain": {"population": 45, "GNP": 10}, "sweden": {"population": 9, "GNP": 8}} }


Más respuestas, junto con los tiempos en la respuesta a esta pregunta: ¿Cuál es la forma más eficiente de emitir una lista como marco de datos?

La forma más rápida, que no produce un marco de datos con listas en lugar de vectores para columnas, parece ser (según la respuesta de Martin Morgan):

l <- list(list(col1="a",col2=1),list(col1="b",col2=2)) f = function(x) function(i) unlist(lapply(x, `[[`, i), use.names=FALSE) as.data.frame(Map(f(l), names(l[[1]])))


Para el caso general de listas profundamente anidadas con 3 o más niveles como los obtenidos de un JSON anidado:

myjson <- jsonlite:fromJSON(file("test.json")) tall <- reshape2::melt(myjson)[, c("L1", "L2", "L3", "value")] L1 L2 L3 value 1 2015 spain population 43 2 2015 spain GNP 9 3 2015 sweden population 7 4 2015 sweden GNP 6 5 2016 spain population 45 6 2016 spain GNP 10 7 2016 sweden population 9 8 2016 sweden GNP 8

Considere el enfoque de melt() para convertir primero la lista anidada a un formato alto:

wide <- reshape2::dcast(tall, L1+L2~L3) # left side of the formula defines the rows/observations and the # right side defines the variables/measurements L1 L2 GNP population 1 2015 spain 9 43 2 2015 sweden 6 7 3 2016 spain 10 45 4 2016 sweden 8 9

seguido por dcast() luego a lo ancho nuevamente en un conjunto de datos ordenado donde cada variable forma una columna y cada observación forma una fila:

do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))


Puedes usar el paquete plyr . Por ejemplo una lista anidada del formulario.

l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3) , b = list(var.1 = 4, var.2 = 5, var.3 = 6) , c = list(var.1 = 7, var.2 = 8, var.3 = 9) , d = list(var.1 = 10, var.2 = 11, var.3 = 12) )

ahora tiene una longitud de 4 y cada lista en l contiene otra lista de la longitud 3. Ahora puede ejecutar

library (plyr) df <- ldply (l, data.frame)

y debería obtener el mismo resultado que en la respuesta @Marek y @nico.


Reshape2 produce el mismo resultado que el ejemplo de plyr anterior:

library(reshape2) l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3) , b = list(var.1 = 4, var.2 = 5, var.3 = 6) , c = list(var.1 = 7, var.2 = 8, var.3 = 9) , d = list(var.1 = 10, var.2 = 11, var.3 = 12) ) l <- melt(l) dcast(l, L1 ~ L2)

rendimientos

L1 var.1 var.2 var.3 1 a 1 2 3 2 b 4 5 6 3 c 7 8 9 4 d 10 11 12

Si estuviera casi sin píxeles, podría hacer todo esto en 1 línea w / recast ().


Supongamos que su lista se llama L ,

data.frame(Reduce(rbind, L))


Suponiendo que su lista de listas se llama l :

df <- data.frame(matrix(unlist(l), nrow=132, byrow=T))

Lo anterior convertirá todas las columnas de caracteres en factores, para evitar esto, puede agregar un parámetro a la llamada data.frame ():

df <- data.frame(matrix(unlist(l), nrow=132, byrow=T),stringsAsFactors=FALSE)


data.frame(t(sapply(mylistlist,c)))

sapply convierte en una matriz. data.frame convierte la matriz en un marco de datos.


l <- replicate(10,list(sample(letters, 20))) a <-lapply(l[1:10],data.frame) do.call("cbind", a)