Identifying and modifying list-column cells in a dataframe

Viewed 153

I used pivot_wider to spread my data. However, there were duplicate rows (although I'm still not clear why), so the duplicates were stored in "list_columns." I'm now trying to identify which cells have been stored as lists, and I'd like to replace those values with just the first element in the list.

Example:

df <- tibble(
    a = list(c("a", "b"), "c"),
    b = list(1, 2),
    c = c(11, 22)
)

When I view this df in RStudio View(df) the first cell in the a column shows up as c("a", "b") (see screenshot). enter image description here

I'm trying to identify the cells in my data.frame that are stored in that c() form, and then I want to replace those values with just the first element in the list. I've tried is.vector(), is.list(), but I can't seem to figure out what the actual class type is of the values stored in that way, or how to operate on them.

3 Answers

One option using dplyr could be:

df %>%
 rowwise() %>%
 mutate_all(~ unlist(.)[1])

  a         b     c
  <chr> <dbl> <dbl>
1 a         1    11
2 c         2    22

Or with the addition of purrr:

df %>%
 mutate_all(~ unlist(map(., `[`, 1)))

Using the new across function from dplyr

library(dplyr)
library(purrr)

df %>% 
  mutate(across(everything(), ~unlist(map(.x, `[`, 1))))

Output

# A tibble: 2 x 3
#   a         b     c
#   <chr> <dbl> <dbl>
# 1 a         1    11
# 2 c         2    22

An option with mutate/across and map/unnest

library(purrr)
library(tidyr)
library(dplyr)
df %>% 
    mutate(across(where(is.list), ~ map(., first))) %>% 
    unnest()
# A tibble: 2 x 3
#  a         b     c
#  <chr> <dbl> <dbl>
#1 a         1    11
#2 c         2    22
Related