list 将列表转换为数据框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4227223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert a list to a data frame
提问by Btibert3
I have a nested list of data. Its length is 132 and each item is a list of length 20. Is there a quickway to convert this structure into a data frame that has 132 rows and 20 columns of data?
我有一个嵌套的数据列表。它的长度是 132,每一项都是一个长度为 20 的列表。有没有一种快速的方法可以把这个结构转换成一个有 132 行和 20 列数据的数据框?
Here is some sample data to work with:
以下是一些可以使用的示例数据:
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
采纳答案by nico
Assuming your list of lists is called l
:
假设您的列表列表被称为l
:
df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=T))
The above will convert all character columns to factors, to avoid this you can add a parameter to the data.frame() call:
以上将所有字符列转换为因子,为避免这种情况,您可以向 data.frame() 调用添加一个参数:
df <- data.frame(matrix(unlist(l), nrow=132, byrow=T),stringsAsFactors=FALSE)
回答by Marek
With rbind
和 rbind
do.call(rbind.data.frame, your_list)
Edit: Previous version return data.frame
of list
's instead of vectors (as @IanSudbery pointed out in comments).
编辑:以前的版本回报data.frame
的list
的载体,而不是(如@IanSudbery在评论中指出)。
回答by mropa
You can use the plyr
package.
For example a nested list of the form
您可以使用该plyr
软件包。例如表单的嵌套列表
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)
)
has now a length of 4 and each list in l
contains another list of the length 3.
Now you can run
现在长度为 4 并且每个列表都l
包含另一个长度为 3 的列表。现在您可以运行
library (plyr)
df <- ldply (l, data.frame)
and should get the same result as in the answer @Marek and @nico.
并且应该得到与@Marek 和@nico 的答案相同的结果。
回答by Alex Brown
data.frame(t(sapply(mylistlist,c)))
data.frame(t(sapply(mylistlist,c)))
sapply
converts it to a matrix.
data.frame
converts the matrix to a data frame.
sapply
将其转换为矩阵。
data.frame
将矩阵转换为数据框。
回答by jdeng
assume your list is called L
,
假设你的名单被称为L
,
data.frame(Reduce(rbind, L))
回答by mnel
The package data.table
has the function rbindlist
which is a superfast implementation of do.call(rbind, list(...))
.
该包data.table
具有rbindlist
超快实现的功能do.call(rbind, list(...))
。
It can take a list of lists
, data.frames
or data.tables
as input.
它可以采取的一个列表 lists
,data.frames
或data.tables
作为输入。
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)
This returns a data.table
inherits from data.frame
.
这将返回一个data.table
继承自data.frame
.
If you reallywant to convert back to a data.frame use as.data.frame(DT)
如果你真的想转换回 data.frame 使用as.data.frame(DT)
回答by Matt Dancho
The tibble
package has a function enframe()
that solves this problem by coercing nested list
objects to nested tibble
("tidy" data frame) objects. Here's a brief example from R for Data Science:
该tibble
包具有enframe()
通过将嵌套list
对象强制为嵌套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.
由于您的列表中有多个嵌套l
,因此您可以使用unlist(recursive = FALSE)
删除不必要的嵌套以获得单个分层列表,然后传递给enframe()
。我tidyr::unnest()
过去常常将输出取消嵌套到一个单一级别的“整洁”数据框中,其中有两列(一列用于组name
,另一列用于与组的观察value
)。如果您想要使列变宽,您可以使用add_column()
仅重复值的顺序 132 次的方式添加列。然后只是spread()
价值观。
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>
回答by sbha
Depending on the structure of your lists there are some tidyverse
options that work nicely with unequal length lists:
根据列表的结构,有一些tidyverse
选项可以很好地处理不等长列表:
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
You can also mix vectors and data frames:
您还可以混合向量和数据框:
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
回答by Hyman Ryan
Reshape2 yields the same output as the plyr example above:
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)
yields:
产量:
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
If you were almost out of pixels you coulddo this all in 1 line w/ recast().
如果你几乎没有像素,你可以在 1 行 w/recast() 中完成这一切。
回答by SavedByJESUS
This method uses a tidyverse
package (purrr).
此方法使用tidyverse
包 ( purrr)。
The list:
列表:
x <- as.list(mtcars)
Converting it into a data frame (a tibble
more specifically):
将其转换为数据框(tibble
更具体地说):
library(purrr)
map_df(x, ~.x)