我有一个嵌套的数据列表。它的长度是132,每一项是一个长度为20的列表。是否有一种快速的方法可以将这种结构转换为具有132行和20列数据的数据帧?
下面是一些示例数据:
l <- replicate(
132,
as.list(sample(letters, 20)),
simplify = FALSE
)
我有一个嵌套的数据列表。它的长度是132,每一项是一个长度为20的列表。是否有一种快速的方法可以将这种结构转换为具有132行和20列数据的数据帧?
下面是一些示例数据:
l <- replicate(
132,
as.list(sample(letters, 20)),
simplify = FALSE
)
当前回答
l <- replicate(10,list(sample(letters, 20)))
a <-lapply(l[1:10],data.frame)
do.call("cbind", a)
其他回答
Reshape2产生与上面的plyr示例相同的输出:
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)
收益率:
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
如果你几乎没有像素,你可以在一行w/ recast()中完成这一切。
tibble包有一个函数enframe(),它通过将嵌套的列表对象强制转换为嵌套的tibble(“整齐的”数据帧)对象来解决这个问题。下面是R for 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]>
Since you have several nests in your list, l, you can use the unlist(recursive = FALSE) to remove unnecessary nesting to get just a single hierarchical list and then pass to enframe(). I use tidyr::unnest() to unnest the output into a single level "tidy" data frame, which has your two columns (one for the group name and one for the observations with the groups value). If you want columns that make wide, you can add a column using add_column() that just repeats the order of the values 132 times. Then just spread() the values.
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>
包数据。Table中有rbindlist函数,它是do的一个超快速实现。调用(rbind列表(…))。
它可以接受一个列表的列表,data。frame或data。表作为输入。
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)
这会返回一个数据。表继承自data.frame。
如果你真的想转换回data。frame使用as。data。frame(DT)
这是最后对我有用的方法:
do.call(“rbind”, lapply(S1, as.data.frame))
扩展@Marek的回答:如果你想避免字符串变成因素和效率不是一个问题,尝试一下
do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))