有没有办法在 purrr::map 中自动传播 NULL?

Is there a way to automatically propagate NULL in purrr::map?

我有一些数据,其中一些是复制的,一些不是。我只能适合 我的复制数据模型。

library(tidyverse)
d <- tribble(
  ~env, ~val,
  "A",  1,
  "A",  2,
  "B",  3
)

我正在使用 tidyr::nest()purrr::map() 函数来拟合我的模型。 但是,在我用于 map() 的每个函数中,我都必须满足特殊要求 特定数据集不可建模的情况,我已完成 通过

风格的调用
map(col, function(elem){ if(!is.null(elem)) DO_STUFF(elem) else NULL})

一段时间后,我设法将这种行为提取为一个 purrr 风格的副词 接受另一个函数并将其包装起来的函数,使得这种行为 NULL 个元素是自动的:

maybe <- function(fun){
  function(val,...){ if(!is.null(val)) fun(val, ...) else NULL}
}

然而,这让我想知道:我是否在复制行为 已经可以使用 tidyverse 函数存档了吗?

奖金问题:在函数式编程中是否有像 maybe 这样的函数的词?


这是一个测试我的副词的例子:

简单模型:环境 A 中的数据均值,而环境 A 中的数据没有模型 环境 B(因为数据是未复制的:)

modelFuns <- list(A = mean, B = NULL)

按环境对数据进行分组并为每个组确定合适的模型

d <- d %>% group_by(env) %>% nest(.key = "data")
d %<>% mutate(model = modelFuns[env])
d

## # A tibble: 2 x 3
##   env   data             model 
##   <chr> <list>           <list>
## 1 A     <tibble [2 × 1]> <fn>  
## 2 B     <tibble [1 × 1]> <NULL>

执行建模:

d %<>% mutate(out = pmap(list(model, data), maybe(function(m,d) m(d$val))))
d

## # A tibble: 2 x 4
##   env   data             model  out      
##   <chr> <list>           <list> <list>   
## 1 A     <tibble [2 × 1]> <fn>   <dbl [1]>
## 2 B     <tibble [1 × 1]> <NULL> <NULL>

这等同于以下不使用我的 maybe 副词的代码:

d %<>% mutate(out = pmap(list(model, data), function(m,d){if(!is.null(m)) m(d$val) else NULL}))
d

## # A tibble: 2 x 4
##   env   data             model  out      
##   <chr> <list>           <list> <list>   
## 1 A     <tibble [2 × 1]> <fn>   <dbl [1]>
## 2 B     <tibble [1 × 1]> <NULL> <NULL>

可能存在值或可能存在 NULL 的事实传播到 我想对下游的建模结果做的一切,这是 为什么副词 maybe 有用。这样的事情是否已经存在 在 tidyverse 中?

isModelNice <- function(val) val > 0
d %<>% mutate(nice = map(out, maybe(isModelNice)))
d

## # A tibble: 2 x 5
##   env   data             model  out       nice     
##   <chr> <list>           <list> <list>    <list>   
## 1 A     <tibble [2 × 1]> <fn>   <dbl [1]> <lgl [1]>
## 2 B     <tibble [1 × 1]> <NULL> <NULL>    <NULL>

你可以使用 purrr::possibly() 吗?

library(tidyverse)

d <- tribble(
  ~env, ~val,
  "A",  1,
  "A",  2,
  "B",  3
)

modelFuns <- list(A = mean, B = NULL)

d %>% group_by(env) %>% 
  nest(.key = "data") %>% 
  mutate(model = modelFuns[env]) %>% 
  mutate(out = pmap(list(model, data), possibly(function(m,d) m(d$val), NULL)))