0
votes

I have a tibble with list-columns. One of those (let's call it info column) contains named lists. For each row of the tibble, I want to mutate a new list-column that will contain a vector (nested). The elements of that vector will correspond to the names of a named list in the adjacent "info" list-column.

Example

my_tibble <-
  structure(
  list(
    var_name = c("artworks", "sports","independence", "gender"),
    info = list(
      list(
        `Vincent van Gogh` = "The Starry Night",
        `Leonardo da Vinci` = "Mona Lisa",
        `Johannes Vermeer` = "Girl with a Pearl Earring",
        `Sandro Botticelli` = "The Birth of Venus",
        `Grant Wood` = "American Gothic"
      ),
      NULL,
      list(
        `1776` = "USA",
        `1818` = "Argentina",
        `1956` = "Morocco"
      ),
      list(male = "XY chromosomes",
           female = "XX chromosomes")
    )
  ),
  row.names = c(NA, -4L),
  class = c("tbl_df", "tbl", "data.frame")
)

> my_tibble
## # A tibble: 4 x 2
##   var_name     info            
##   <chr>        <list>          
## 1 artworks     <named list [5]>
## 2 sports       <NULL>          
## 3 independence <named list [3]>
## 4 gender       <named list [2]>

Desired Output

var_name       info               names_of        
<chr>          <list>             <list>           
1 artworks     <named list [5]>   <chr [5]>     # c("Vincent van Gogh", "Leonardo da Vinci", "Johannes Vermeer", "Sandro Botticelli", "Grant Wood")
2 sports       <NULL>             <chr [1]>     # c("seems_null") 
3 independence <named list [3]>   <dbl [3]>     # c(1776, 1818, 1956)       
4 gender       <named list [2]>   <chr [2]>     # c("male", "female")

My attempt

I want to mutate a new list-column, that checks the info column. If info isn't NULL, the new list-column will contain a vector with the names of the list nested in info; otherwise, put a string "seems_null" in the mutated list-column.

library(dplyr)
library(purrr)

my_tibble %>%
  mutate(names_of = map_chr(info, ~ ifelse(is.null(.x), "seems_null", names(.x))))

## # A tibble: 4 x 3
##   var_name     info             names_of        
##   <chr>        <list>           <chr>           
## 1 artworks     <named list [5]> Vincent van Gogh
## 2 sports       <NULL>           seems_null      
## 3 independence <named list [3]> 1776            
## 4 gender       <named list [2]> male  

Unfortunately, this returns only the first name from the list in info.

I also tried using pmap() as shown in this answer, but it didn't work:

my_list %>%
  mutate(names_of = map_chr(info, ~ ifelse(is.null(.x), list("seems_null"), pmap(.x, names(.x)[c(...)])  ) ))

Error: Problem with mutate() input names_of.
x invalid subscript type 'list'
i Input names_of is map_chr(...).

I'll appreciate any help!

1

1 Answers

1
votes

Perform the calculation rowwise like this:

res <- my_tibble %>%
   rowwise %>%
   mutate(names_of = list(if (is.null(info)) "seems_null" else names(info))) %>%
   ungroup

giving:

> res
# A tibble: 4 x 3
  var_name     info             names_of 
  <chr>        <list>           <list>   
1 artworks     <named list [5]> <chr [5]>
2 sports       <NULL>           <chr [1]>
3 independence <named list [3]> <chr [3]>
4 gender       <named list [2]> <chr [2]>