Bti*_*rt3 470 r list dataframe
我有一个嵌套的数据列表.它的长度是132,每个项目都是长度为20的列表.是否有一种快速方法将此结构转换为具有132行和20列数据的数据框?
以下是一些要使用的示例数据:
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
Run Code Online (Sandbox Code Playgroud)
Mar*_*rek 436
同 rbind
do.call(rbind.data.frame, your_list)
Run Code Online (Sandbox Code Playgroud)
编辑:以前的版本回报data.frame的list的载体,而不是(如@IanSudbery在评论中指出).
nic*_*ico 344
假设您的列表列表被调用l:
df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=T))
Run Code Online (Sandbox Code Playgroud)
以上将所有字符列转换为因子,为避免这种情况,您可以向data.frame()调用添加一个参数:
df <- data.frame(matrix(unlist(l), nrow=132, byrow=T),stringsAsFactors=FALSE)
Run Code Online (Sandbox Code Playgroud)
mro*_*opa 127
你可以使用这个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)
)
Run Code Online (Sandbox Code Playgroud)
现在长度为4,每个列表l包含另一个长度为3的列表.现在你可以运行了
library (plyr)
df <- ldply (l, data.frame)
Run Code Online (Sandbox Code Playgroud)
并且应该得到与答案@Marek和@nico相同的结果.
Ale*_*own 90
data.frame(t(sapply(mylistlist,c)))
sapply将其转换为矩阵.
data.frame将矩阵转换为数据帧.
jde*_*eng 64
假设你的名单被调用L,
data.frame(Reduce(rbind, L))
Run Code Online (Sandbox Code Playgroud)
mne*_*nel 56
该软件包data.table具有rbindlist一个超快速实现的功能do.call(rbind, list(...)).
它可以采取的一个列表 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)
Run Code Online (Sandbox Code Playgroud)
这将返回一个data.table继承data.frame.
如果你真的想转换回data.frame使用as.data.frame(DT)
Mat*_*cho 30
该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]>
Run Code Online (Sandbox Code Playgroud)
由于列表中有多个嵌套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>
Run Code Online (Sandbox Code Playgroud)
Jac*_*yan 16
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)
Run Code Online (Sandbox Code Playgroud)
收益率:
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
Run Code Online (Sandbox Code Playgroud)
如果你几乎没有像素,你可以在1行w/recast()中完成这一切.
sbh*_*bha 15
根据列表的结构,有一些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
Run Code Online (Sandbox Code Playgroud)
您还可以混合矢量和数据框:
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
Run Code Online (Sandbox Code Playgroud)
Sav*_*SUS 11
此方法使用tidyverse包(purrr)。
列表:
x <- as.list(mtcars)
Run Code Online (Sandbox Code Playgroud)
将其转换为数据帧(tibble更具体地说):
library(purrr)
map_df(x, ~.x)
Run Code Online (Sandbox Code Playgroud)
Ahm*_*mad 11
以下简单的命令对我有用:
\nmyDf <- as.data.frame(myList)\nRun Code Online (Sandbox Code Playgroud)\n参考(Quora答案)
\n> myList <- list(a = c(1, 2, 3), b = c(4, 5, 6))\n> myList\n$a\n[1] 1 2 3\n \n$b\n[1] 4 5 6\n \n> myDf <- as.data.frame(myList)\n a b\n1 1 4\n2 2 5\n3 3 6\n> class(myDf)\n[1] "data.frame"\nRun Code Online (Sandbox Code Playgroud)\n但是如果\xe2\x80\x99s 不明显如何将列表转换为数据框,这将会失败:
\n> myList <- list(a = c(1, 2, 3), b = c(4, 5, 6, 7))\n> myDf <- as.data.frame(myList)\nRun Code Online (Sandbox Code Playgroud)\n\n\n(function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, :\narguments 暗示不同的行数: 3, 4
\n
注意:答案针对问题标题,可能会跳过问题的一些细节
\n更多答案,以及这个问题答案的时间安排: 将列表作为数据框架的最有效方法是什么?
最快的方式是,不会产生带有列表而不是列的向量的数据帧(来自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]])))
Run Code Online (Sandbox Code Playgroud)
小智 9
延伸@ Marek的答案:如果你想避免字符串被转化为因素和效率不是一个值得关注的尝试
do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))
Run Code Online (Sandbox Code Playgroud)
对于具有3个或更多级别的深层嵌套列表的一般情况,例如从嵌套JSON获得的级别:
{
"2015": {
"spain": {"population": 43, "GNP": 9},
"sweden": {"population": 7, "GNP": 6}},
"2016": {
"spain": {"population": 45, "GNP": 10},
"sweden": {"population": 9, "GNP": 8}}
}
Run Code Online (Sandbox Code Playgroud)
考虑melt()首先将嵌套列表转换为高格式的方法:
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
Run Code Online (Sandbox Code Playgroud)
然后dcast()再广泛进入一个整洁的数据集,其中每个变量形成一列,每个观察形成一行:
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
Run Code Online (Sandbox Code Playgroud)
如果您的列表具有相同尺寸的元素,您可以使用bind_rowstidyverse 中的函数。
# Load the tidyverse
Library(tidyverse)
# make a list with elements having same dimensions
My_list <- list(a = c(1, 4, 5), b = c(9, 3, 8))
## Bind the rows
My_list %>% bind_rows()
Run Code Online (Sandbox Code Playgroud)
结果是一个包含两行的数据框。
有时您的数据可能是相同长度的矢量列表的列表.
lolov = list(list(c(1,2,3),c(4,5,6)), list(c(7,8,9),c(10,11,12),c(13,14,15)) )
Run Code Online (Sandbox Code Playgroud)
(内部向量也可以是列表,但我正在简化以使其更容易阅读).
然后您可以进行以下修改.请记住,您可以一次取消一个级别:
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
Run Code Online (Sandbox Code Playgroud)
现在使用其他答案中提到的您最喜欢的方法:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
676505 次 |
| 最近记录: |