这种类型的 "将列表扁平化为数据框 "的问题已经被问过几次了,然而我找不到对我的特殊问题有帮助的解决方案。我在下面做了一个小例子。一般来说,当使用 httr
在R中从apis中获取数据,我用过的大多数数据apis都以类似嵌套列表的格式返回数据,看起来是这样的。
nested_list = list(
list(
name = 'joe',
match = 13,
team = list(
list(
name = 'teama'
),
list(
name = 'teamb'
)
)
),
list(
name = 'tom',
match = 15,
team = list(
list(
name = 'teamc'
),
list(
name = 'teamd'
)
)
)
)
我一直在研究一个很好的函数来扁平化嵌套列表的列表,因为扁平的数据框在R中更容易进行分析。 这是我目前扁平化为2D的方法。
nested_list %>%
purrr::map(unlist) %>%
purrr::map(t) %>%
purrr::map(as_tibble) %>%
dplyr::bind_rows() %>%
readr::type_convert() # optional, to format column types
这种方法一般来说效果还不错,但是在 as_tibble
map被调用,如果嵌套的list-of-list中有重复的键,那么就会用列名V1、V2、V3等代替。我在下面展示了导致这个问题的步骤。
unlist
> nested_list %>% purrr::map(unlist)
[[1]]
name match team.name team.name
"joe" "13" "teama" "teamb"
[[2]]
name match team.name team.name
"tom" "15" "teamc" "teamd"
拆单
> nested_list %>% purrr::map(unlist) %>% purrr::map(t)
[[1]]
name match team.name team.name
[1,] "joe" "13" "teama" "teamb"
[[2]]
name match team.name team.name
[1,] "tom" "15" "teamc" "teamd"
解列和转置以及as_tibble。
> nested_list %>% purrr::map(unlist) %>% purrr::map(t) %>% purrr::map(as_tibble)
[[1]]
# A tibble: 1 x 4
name match team.name V4
<chr> <chr> <chr> <chr>
1 joe 13 teama teamb
[[2]]
# A tibble: 1 x 4
name match team.name V4
<chr> <chr> <chr> <chr>
1 tom 15 teamc teamd
在我的完整数据集中,有很多重复的列名,太多了,无法用代码手动修复更新这些列名。相反,如果能更好地处理重复的列名,那就更好了(也许可以用一个 team.name.1
和 team.name.2
).
有没有其他方法可以将这个list-of-list扁平化,保留这样的列名?如果有任何帮助,我将非常感激!
as_tibble
中有一个参数 .name_repair
. 设置为 "unique"
做你想做的事。
nested_list %>%
purrr::map(unlist) %>%
purrr::map(t) %>%
purrr::map(as_tibble, .name_repair = "unique") %>%
dplyr::bind_rows() %>%
readr::type_convert()
# A tibble: 2 x 4
name match team.name...3 team.name...4
<chr> <dbl> <chr> <chr>
1 joe 13 teama teamb
2 tom 15 teamc teamd
请注意,我们将这个选项传递给 purrr::map()
调用,并将其传递给 as_tibble
呼叫。
另一个提示:如果你更换了上一个 purrr::map()
与 purrr:map_dfr()
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ bind_rows()
是自动完成的。