从 R 中的 tibble 创建列表列表(tidyverse)
Create list of lists from tibble in R (tidyverse)
我正在尝试做一些看起来很简单的事情,但我无法弄清楚。我有这样的烦恼:
> df <- tibble::tribble(
~col_a, ~col_b,
1, "A",
2, "B",
3, "C",
)
> df
# # A tibble: 3 x 2
# col_a col_b
# <dbl> <chr>
# 1 A
# 2 B
# 3 C
我想把它变成一个看起来像这样的列表
> str(res_list)
# List of 3
# $ :List of 2
# ..$ col_a: num 1
# ..$ col_b: chr "A"
# $ :List of 2
# ..$ col_a: num 2
# ..$ col_b: chr "B"
# $ :List of 2
# ..$ col_a: num 3
# ..$ col_b: chr "C"
我尝试了很多使用基础 apply
和 dplyr::rowwise
的方法,但没有一个是正确的。在 purrr::pmap
的文档中,我认为我找到了答案:
f. A function, formula, or vector (not necessarily atomic)...
If character vector, numeric vector, or list, it is converted to an extractor function. Character vectors index by name...
所以我想,这应该行得通:pmap(df, c("col_a", "col_b"))
并且应该为每个元素(行)提取那些列和 return 提取列表的列表。但是当我 运行 我得到:
Error in pluck(x, "col_a", "col_b", .default = NULL) :
argument "x" is missing, with no default
我半理解这个错误,但我认为我正在遵循文档中的用法。也许这只是 purrr 中的一个错误?
无论如何,欢迎对潜在的 purrr 错误发表评论,但实际上我只是想创建此列表。非常感谢任何帮助。
您可以使用 group_split()
(如果您愿意,也可以使用基础 split()
):
library(dplyr)
library(purrr)
df %>%
group_split(row_number(), .keep = FALSE) %>%
map(as.list)
其中 str()
给出:
List of 3
$ :List of 2
..$ col_a: num 1
..$ col_b: chr "A"
$ :List of 2
..$ col_a: num 2
..$ col_b: chr "B"
$ :List of 2
..$ col_a: num 3
..$ col_b: chr "C"
或:
lapply(split(df, 1:nrow(df)),
as.list)
您可以使用 asplit()
.
type.convert(lapply(asplit(df, 1), as.list), as.is = T)
或by()
`attributes<-`(by(df, 1:nrow(df), as.list), NULL)
两个str()
都给
List of 3
$ :List of 2
..$ col_a: int 1
..$ col_b: chr "A"
$ :List of 2
..$ col_a: int 2
..$ col_b: chr "B"
$ :List of 2
..$ col_a: int 3
..$ col_b: chr "C"
我们可以使用pmap
library(purrr)
dflist <- df %>%
pmap(~ list(...))
str(dflist)
#List of 3
# $ :List of 2
# ..$ col_a: num 1
# ..$ col_b: chr "A"
# $ :List of 2
# ..$ col_a: num 2
# ..$ col_b: chr "B"
# $ :List of 2
# ..$ col_a: num 3
# ..$ col_b: chr "C"
我正在尝试做一些看起来很简单的事情,但我无法弄清楚。我有这样的烦恼:
> df <- tibble::tribble(
~col_a, ~col_b,
1, "A",
2, "B",
3, "C",
)
> df
# # A tibble: 3 x 2
# col_a col_b
# <dbl> <chr>
# 1 A
# 2 B
# 3 C
我想把它变成一个看起来像这样的列表
> str(res_list)
# List of 3
# $ :List of 2
# ..$ col_a: num 1
# ..$ col_b: chr "A"
# $ :List of 2
# ..$ col_a: num 2
# ..$ col_b: chr "B"
# $ :List of 2
# ..$ col_a: num 3
# ..$ col_b: chr "C"
我尝试了很多使用基础 apply
和 dplyr::rowwise
的方法,但没有一个是正确的。在 purrr::pmap
的文档中,我认为我找到了答案:
f. A function, formula, or vector (not necessarily atomic)...
If character vector, numeric vector, or list, it is converted to an extractor function. Character vectors index by name...
所以我想,这应该行得通:pmap(df, c("col_a", "col_b"))
并且应该为每个元素(行)提取那些列和 return 提取列表的列表。但是当我 运行 我得到:
Error in pluck(x, "col_a", "col_b", .default = NULL) :
argument "x" is missing, with no default
我半理解这个错误,但我认为我正在遵循文档中的用法。也许这只是 purrr 中的一个错误?
无论如何,欢迎对潜在的 purrr 错误发表评论,但实际上我只是想创建此列表。非常感谢任何帮助。
您可以使用 group_split()
(如果您愿意,也可以使用基础 split()
):
library(dplyr)
library(purrr)
df %>%
group_split(row_number(), .keep = FALSE) %>%
map(as.list)
其中 str()
给出:
List of 3
$ :List of 2
..$ col_a: num 1
..$ col_b: chr "A"
$ :List of 2
..$ col_a: num 2
..$ col_b: chr "B"
$ :List of 2
..$ col_a: num 3
..$ col_b: chr "C"
或:
lapply(split(df, 1:nrow(df)),
as.list)
您可以使用 asplit()
.
type.convert(lapply(asplit(df, 1), as.list), as.is = T)
或by()
`attributes<-`(by(df, 1:nrow(df), as.list), NULL)
两个str()
都给
List of 3
$ :List of 2
..$ col_a: int 1
..$ col_b: chr "A"
$ :List of 2
..$ col_a: int 2
..$ col_b: chr "B"
$ :List of 2
..$ col_a: int 3
..$ col_b: chr "C"
我们可以使用pmap
library(purrr)
dflist <- df %>%
pmap(~ list(...))
str(dflist)
#List of 3
# $ :List of 2
# ..$ col_a: num 1
# ..$ col_b: chr "A"
# $ :List of 2
# ..$ col_a: num 2
# ..$ col_b: chr "B"
# $ :List of 2
# ..$ col_a: num 3
# ..$ col_b: chr "C"