在 tibble 中,通过改变新的列表列从命名列表中提取名称

In a tibble, extract names from named lists by mutating a new list-column

我对列表列很感兴趣。其中之一(我们称之为 info 列)包含命名列表。对于 tibble 的每一行,我想改变一个包含向量(嵌套)的新列表列。该向量的元素将对应于相邻“info”列表列中命名列表的 names

例子

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]>

期望的输出

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")

我的尝试

我想改变一个新的列表列,检查 info 列。如果 info 不是 NULL,新的列表列将包含一个向量,其中 names 嵌套在 info 中;否则,将字符串 "seems_null" 放入变异的列表列中。

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  

不幸的是,这 returns 只是 info 中列表中的第一个名字。

我也尝试过使用 pmap(),如 所示,但没有成功:

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(...).

我将不胜感激!

像这样按行执行计算:

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

给予:

> 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]>