I'm trying to do something that seems very simple, but I cannot figure it out. I have a tibble like so:
> 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
and I want to turn it into a list that looks like this
> 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"
I tried a number of things using base apply
and dplyr::rowwise
but nothing worked quite right. In the docs for purrr::pmap
I thought I found the answer:
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...
So I thought, great this should work: pmap(df, c("col_a", "col_b"))
and that should extract those columns for each element (row) and return a list of the extracted lists. But when I run that I get:
Error in pluck(x, "col_a", "col_b", .default = NULL) :
argument "x" is missing, with no default
I semi-understand this error, but I think I'm following the usage in the docs. Maybe this is just a bug in purrr?
Anyway, commentary on the potential purrr bug is welcome, but really I'm just trying to create this list. Any help is very appreciated.
Tibbles are actually lists. Every tibble is a named list of vectors, each of the same length.
Tibbles can also have columns that are lists. These columns are (appropriately) called list columns. List columns are more flexible than normal, atomic vector columns.
Use options(pillar. width = Inf) to always print all columns, regardless of the width of the screen. This will change the default behavior for all tibbles.
You can use group_split()
(or base split()
if you prefer):
library(dplyr)
library(purrr)
df %>%
group_split(row_number(), .keep = FALSE) %>%
map(as.list)
Where str()
gives:
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"
Or:
lapply(split(df, 1:nrow(df)),
as.list)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With