Сделать элементы NA в зависимости от функции предиката - PullRequest
0 голосов
/ 03 июня 2018

Как я могу легко изменить элементы списка или векторов на NAs в зависимости от предиката?

Мне нужно сделать это за один вызов для плавной интеграции в вызовы dplyr::mutate и т. Д..

ожидаемый результат:

make_na(1:10,`>`,5)
# [1]  1  2  3  4  5 NA NA NA NA NA

my_list <- list(1,"a",NULL,character(0))    
make_na(my_list, is.null)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] "a"
# 
# [[3]]
# [1] NA
# 
# [[4]]
# character(0)

Примечание:

Я ответил на мой вопрос, поскольку у меня есть одно решение, но я будусчастлив получить альтернативные решения.Также, возможно, эта функциональность уже есть в базе R или упакована в известную библиотеку

Вдохновлен моим разочарованием в моем ответе на этот пост

1 Ответ

0 голосов
/ 03 июня 2018

Мы можем построить следующую функцию:

make_na <- function(.x,.predicate,...) {
  is.na(.x) <- sapply(.x,.predicate,...)
  .x
}

Или немного лучше использовать магию purrr:

make_na <- function(.x,.predicate,...) {
  if (requireNamespace("purrr", quietly = TRUE)) {
    is.na(.x) <- purrr::map_lgl(.x,.predicate,...)
  } else {
    if("formula" %in% class(.predicate))
      stop("Formulas aren't supported unless package 'purrr' is installed") 
    is.na(.x) <- sapply(.x,.predicate,...)
  }
  .x
}

Таким образом, мы будем использовать purrr::map_lgl если доступна библиотека purrr, sapply в противном случае.

Некоторые примеры:

make_na <- function(.x,.predicate,...) {
  is.na(.x) <- purrr::map_lgl(.x,.predicate,...)
  .x
}

Некоторые варианты использования:

make_na(1:10,`>`,5)
# [1]  1  2  3  4  5 NA NA NA NA NA

my_list <- list(1,"a",NULL,character(0))
make_na(my_list, is.null)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] "a"
# 
# [[3]]
# [1] NA
# 
# [[4]]
# character(0)

make_na(my_list, function(x) length(x)==0)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] "a"
# 
# [[3]]
# [1] NA
# 
# [[4]]
# [1] NA

Если purrrУстановленный мы можем использовать эту короткую форму:

make_na(my_list, ~length(.x)==0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...