将多层列表列表转换为data.frame?
Convert multi-layer list of lists to a data.frame?
假设我有以下内容:
library(httr)
foo <- content(GET(paste0("https://api.cryptowat.ch/markets/kraken/ethusd/ohlc?after=1483228800&before=9999999999&periods=86400")))
结果 foo
是 2 个附加列表的列表:result
和 allowance
。我需要将 foo$result
(下方)展平为 data.frame
.
> foo
$`86400`[[311]]
$`86400`[[311]][[1]]
[1] 1510012800
$`86400`[[311]][[2]]
[1] 295.1
$`86400`[[311]][[3]]
[1] 304.21
$`86400`[[311]][[4]]
[1] 291.3
$`86400`[[311]][[5]]
[1] 298.5
$`86400`[[311]][[6]]
[1] 13792.92
$`86400`[[311]][[7]]
[1] 0
$`86400`[[312]]
$`86400`[[312]][[1]]
[1] 1510099200
$`86400`[[312]][[2]]
[1] 298.5
$`86400`[[312]][[3]]
[1] 303.3
$`86400`[[312]][[4]]
[1] 287.28
$`86400`[[312]][[5]]
[1] 292.07
$`86400`[[312]][[6]]
[1] 32132.04
$`86400`[[312]][[7]]
[1] 0
...
...
data.frame
应该有 nrow
等于 length(foo$result[[1]])
和 ncol
等于 7:
1510012800 295.1 304.21 291.3 298.5 13792.92 0
1510099200 298.5 303.3 287.28 292.07 32132.04 0
...
...
这是使用 lapply
或类似方法执行此操作的快速方法吗?我尝试了 plyr
包中的 ldply
函数,如下所示: lapply(foo$result[[1]], FUN = ldply, .fun = data.frame)
但这仍然是 returns 列表列表。
有什么想法吗?
您可以使用 purrr
中的 map
和 reduce
,结合 dplyr::bind_rows
library(httr)
library(purrr)
library(dplyr)
foo <- content(GET(paste0("https://api.cryptowat.ch/markets/kraken/ethusd/ohlc?after=1483228800&before=9999999999&periods=86400")))
nm <- paste0("X",1:7)
foo$result[[1]] %>%
map(unlist) %>%
map(~setNames(.x, nm)) %>%
reduce(bind_rows)
# A tibble: 354 x 7
X1 X2 X3 X4 X5 X6 X7
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1483228800 8.14884 8.21477 7.94881 8.06999 42388.83 0
2 1483315200 8.10000 8.56100 8.05109 8.19950 53422.02 0
3 1483401600 8.19950 8.47500 8.10000 8.39650 39187.21 0
4 1483488000 8.36780 10.09948 8.25668 9.56690 234379.75 0
5 1483574400 9.63000 11.12499 9.42001 11.02000 210981.02 0
6 1483660800 11.09979 11.63786 9.10000 10.31859 223963.44 0
7 1483747200 10.19690 10.50000 9.50000 10.15870 223224.03 0
8 1483833600 10.14620 10.18403 9.54024 9.87100 110811.07 0
9 1483920000 9.76164 10.47000 9.76164 10.27581 47720.22 0
10 1484006400 10.30282 10.84499 10.10007 10.40000 29018.72 0
# ... with 344 more rows
这是一个基于 R 的解决方案:
df <- as.data.frame(matrix(unlist(foo$result[[1]]), ncol = 7, byrow = TRUE))
head(df);
# V1 V2 V3 V4 V5 V6 V7
#1 1483228800 8.14884 8.21477 7.94881 8.06999 42388.83 0
#2 1483315200 8.10000 8.56100 8.05109 8.19950 53422.02 0
#3 1483401600 8.19950 8.47500 8.10000 8.39650 39187.21 0
#4 1483488000 8.36780 10.09948 8.25668 9.56690 234379.75 0
#5 1483574400 9.63000 11.12499 9.42001 11.02000 210981.02 0
#6 1483660800 11.09979 11.63786 9.10000 10.31859 223963.44 0
解释:unlist
foot$result[[1]]
,将结果向量重新格式化为 7 列 matrix
,并变成 data.frame
。
假设我有以下内容:
library(httr)
foo <- content(GET(paste0("https://api.cryptowat.ch/markets/kraken/ethusd/ohlc?after=1483228800&before=9999999999&periods=86400")))
结果 foo
是 2 个附加列表的列表:result
和 allowance
。我需要将 foo$result
(下方)展平为 data.frame
.
> foo
$`86400`[[311]]
$`86400`[[311]][[1]]
[1] 1510012800
$`86400`[[311]][[2]]
[1] 295.1
$`86400`[[311]][[3]]
[1] 304.21
$`86400`[[311]][[4]]
[1] 291.3
$`86400`[[311]][[5]]
[1] 298.5
$`86400`[[311]][[6]]
[1] 13792.92
$`86400`[[311]][[7]]
[1] 0
$`86400`[[312]]
$`86400`[[312]][[1]]
[1] 1510099200
$`86400`[[312]][[2]]
[1] 298.5
$`86400`[[312]][[3]]
[1] 303.3
$`86400`[[312]][[4]]
[1] 287.28
$`86400`[[312]][[5]]
[1] 292.07
$`86400`[[312]][[6]]
[1] 32132.04
$`86400`[[312]][[7]]
[1] 0
...
...
data.frame
应该有 nrow
等于 length(foo$result[[1]])
和 ncol
等于 7:
1510012800 295.1 304.21 291.3 298.5 13792.92 0
1510099200 298.5 303.3 287.28 292.07 32132.04 0
...
...
这是使用 lapply
或类似方法执行此操作的快速方法吗?我尝试了 plyr
包中的 ldply
函数,如下所示: lapply(foo$result[[1]], FUN = ldply, .fun = data.frame)
但这仍然是 returns 列表列表。
有什么想法吗?
您可以使用 purrr
中的 map
和 reduce
,结合 dplyr::bind_rows
library(httr)
library(purrr)
library(dplyr)
foo <- content(GET(paste0("https://api.cryptowat.ch/markets/kraken/ethusd/ohlc?after=1483228800&before=9999999999&periods=86400")))
nm <- paste0("X",1:7)
foo$result[[1]] %>%
map(unlist) %>%
map(~setNames(.x, nm)) %>%
reduce(bind_rows)
# A tibble: 354 x 7
X1 X2 X3 X4 X5 X6 X7
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1483228800 8.14884 8.21477 7.94881 8.06999 42388.83 0
2 1483315200 8.10000 8.56100 8.05109 8.19950 53422.02 0
3 1483401600 8.19950 8.47500 8.10000 8.39650 39187.21 0
4 1483488000 8.36780 10.09948 8.25668 9.56690 234379.75 0
5 1483574400 9.63000 11.12499 9.42001 11.02000 210981.02 0
6 1483660800 11.09979 11.63786 9.10000 10.31859 223963.44 0
7 1483747200 10.19690 10.50000 9.50000 10.15870 223224.03 0
8 1483833600 10.14620 10.18403 9.54024 9.87100 110811.07 0
9 1483920000 9.76164 10.47000 9.76164 10.27581 47720.22 0
10 1484006400 10.30282 10.84499 10.10007 10.40000 29018.72 0
# ... with 344 more rows
这是一个基于 R 的解决方案:
df <- as.data.frame(matrix(unlist(foo$result[[1]]), ncol = 7, byrow = TRUE))
head(df);
# V1 V2 V3 V4 V5 V6 V7
#1 1483228800 8.14884 8.21477 7.94881 8.06999 42388.83 0
#2 1483315200 8.10000 8.56100 8.05109 8.19950 53422.02 0
#3 1483401600 8.19950 8.47500 8.10000 8.39650 39187.21 0
#4 1483488000 8.36780 10.09948 8.25668 9.56690 234379.75 0
#5 1483574400 9.63000 11.12499 9.42001 11.02000 210981.02 0
#6 1483660800 11.09979 11.63786 9.10000 10.31859 223963.44 0
解释:unlist
foot$result[[1]]
,将结果向量重新格式化为 7 列 matrix
,并变成 data.frame
。