R语言中如何对tibble内非NULL的列表列元素应用函数
解决方案
你可以通过以下三种常用方案解决这个问题,不需要删除含NULL的行:
方案1:在map的处理逻辑中增加NULL判断
直接在传递给map的匿名函数里先判断元素是否为NULL,是就返回你想要的默认值(比如NA_character_或者空字符串),否则执行原有逻辑:
library(tidyverse) x <- tibble( id = 1:2, var = list(NULL, tibble(x = c("yes", "no"))) ) x %>% mutate(var2 = map_chr(var, ~if(is.null(.x)) { NA_character_ # 也可以换成""返回空字符串 } else { pull(.x) %>% str_c(collapse = ";") }))
运行后结果如下:
# A tibble: 2 × 3 id var var2 <int> <list> <chr> 1 1 <NULL> NA 2 2 <tibble [2 × 1]> yes;no
方案2:用purrr::possibly()包装处理逻辑,指定异常时的默认返回值
possibly()会自动捕获处理过程中的错误,遇到异常时返回你指定的默认值,不需要手动写判断逻辑:
# 先定义包装后的处理函数,遇到错误返回NA_character_ process_var <- possibly(~pull(.x) %>% str_c(collapse = ";"), otherwise = NA_character_) x %>% mutate(var2 = map_chr(var, process_var))
运行结果和方案1完全一致,这种写法更简洁,适合处理逻辑更复杂的场景。
方案3:修复你之前的条件赋值写法
你之前的代码报错是因为case_when右侧的map_chr会先遍历所有var元素(包括NULL)再做匹配,所以还是会触发错误。你可以先初始化默认值,再仅对非NULL的元素做处理:
x %>% mutate(var2 = NA_character_, # 先初始化全为默认值 var2 = if_else(!map_lgl(var, is.null), map_chr(var[!map_lgl(var, is.null)], ~pull(.x) %>% str_c(collapse = ";")), var2))
这种写法和前两种效果一致,更符合你最初的逻辑思路,但写法相对繁琐。
内容的提问来源于stack exchange,提问作者Tabasco
相关产品推荐
相关产品推荐

