У меня есть некоторые данные, некоторые из которых реплицированы, некоторые нет. Я могу только соответствовать
моя модель для реплицированных данных.
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})
Через некоторое время мне удалось извлечь это поведение в наречие в стиле мурлыкания.
функция, которая принимает другую функцию и упаковывает ее так, что это поведение
для NULL
элементов автоматически:
maybe <- function(fun){
function(val,...){ if(!is.null(val)) fun(val, ...) else NULL}
}
Однако это заставило меня задуматься: Дублирую ли я поведение, которое
уже архивируется с помощью функций Tidyverse?
Дополнительный вопрос: есть ли в функциональном программировании слово для такой функции, как maybe
?
Вот пример, чтобы проверить мою наречие:
Простая модель: среднее значение для данных в среде А и отсутствие модели для данных в
среда 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
полезно. Существует ли что-то подобное уже
в тидиверсе?
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>