使用purrr将列表中的NULL元素替换为NA

7
我尝试在map()中将以下列表的NULL元素替换为NA,然后再对清洗后的列表使用rbindlist:
m = list(min = list(id = "min", val = NULL), 
     max = list(id = "max", val = 7), 
     split = list(id = "split", val = "gini"))

str(m)
List of 3
 $ min  :List of 2
  ..$ id : chr "min"
  ..$ val: NULL
 $ max  :List of 2
  ..$ id : chr "max"
  ..$ val: num 7
 $ split:List of 2
  ..$ id : chr "split"
  ..$ val: chr "gini"

我尝试了以下代码: map(m, ~list_modify(.x, new = 8), .default = NA) %>% rbindlist,但不确定为什么 .default = NA 不起作用。从文档示例中推测,可能是因为 .default = NA 仅检查 list_modify 返回的列表的第一层是否为 NULL?将其放置在 list_modify() 中也无效。是否有一种方法在 map 管道内部替换 NULLs 为 NA 而不使用 lapply?

3
你的列表中是否可能在不同的层级包含NULL元素?如果是,你可以使用嵌套的map函数:map(m, function(x) map(x, function(y) ifelse(is.null(y), NA, y))) - Maurits Evers
谢谢@Maurits,是的,它们可以出现在除第一层以外的所有层级。我只需要替换第二层中的NULL,以便使用rbindlist(因为NULL元素长度为0,非NULL元素长度为1)。嵌套映射是否应该在更深层次上工作? - user51462
抱歉,我意识到在我的评论中表达得不够清楚; map(m, function(x) map(x, function(y) ifelse(is.null(y), NA, y))) 只会替换第二层级别的 NULL 条目,所以这应该适用于您的情况。 - Maurits Evers
1个回答

5
使用purrr :: map_depth,您可以指定要替换值的深度:
m = list(min = list(id = "min", val = NULL), 
         max = list(id = "max", val = 7), 
         split = list(id = "split", val = "gini"))

res <- purrr::map_depth(m, 2, ~ifelse(is.null(.x), NA, .x) )
str(res)
#> List of 3
#>  $ min  :List of 2
#>   ..$ id : chr "min"
#>   ..$ val: logi NA
#>  $ max  :List of 2
#>   ..$ id : chr "max"
#>   ..$ val: num 7
#>  $ split:List of 2
#>   ..$ id : chr "split"
#>   ..$ val: chr "gini"

本文使用 reprex工具包 (v2.0.1) 创建于2021-10-18。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接