I'm trying to deepen my ability to work with tibbles and one of the things that frequently causes me problems is when I try working with elements within a list column.
More specifically, while this document claims that "Lists can contain anything, so a list column can be made up of atomic vectors, other lists, tibbles, etc.", in my experience the elements within a list column must also be a list.
Here's a MWE
tbl <- crossing(a = c(letters[1:5]), b = list(NA));
dim(tbl)
# [1] (5,2)
char_vec <- c("a", "b", "cd")
# `char_vec` is an atomic vector, so I expect this to work, but it doesn't
tbl[[1, "b"]] <- char_vec
# Error in `[[<-`:
# ! Assigned data `char_vec` must be compatible with row subscript `1`.
# ✖ 1 row must be assigned.
# ✖ Assigned data has 3 rows.
# ℹ Row updates require a list value. Do you need `list()` or `as.list()`?
# Caused by error in `vectbl_recycle_rhs_rows()`:
# ! Can't recycle input of size 3 to size 1.
# Run `rlang::last_trace()` to see where the error occurred
# This, however, does work
tbl[[1, "b"]] <- list(char_vec)
tbl[[1, "b"]]
# [[1]]
# [1] "a" "b" "cd"
Can I use an atomic vector as an element in a list column and I am just using the wrong syntax or is impossible and, if so, why? I thought a list, and thus a list column, could include any type of valid object.
When I need to assign an element to a list column, I normally use [[
twice:
tbl[["b"]][[1]] = char_vec
tbl
# # A tibble: 5 × 2
# a b
# <chr> <list>
# 1 a <chr [3]>
# 2 b <lgl [1]>
# 3 c <lgl [1]>
# 4 d <lgl [1]>
# 5 e <lgl [1]>
Or if I'm assigning multiple elements, I use [[
and [
:
tbl[["b"]][2:3] = list(1:3, letters)
tbl
# # A tibble: 5 × 2
# a b
# <chr> <list>
# 1 a <chr [3]>
# 2 b <int [3]>
# 3 c <chr [26]>
# 4 d <lgl [1]>
# 5 e <lgl [1]>
This makes sense to me because tbl[["b"]]
is the list
. If I had a list
x = list(1, 1:3, "a")
and I wanted to assign the first element, I'd use x[[1]] = char_vec
. This is the same, except I am using tbl[["b"]]
in place of x
.