根据谓词函数使元素变为NA

3

如何根据谓词轻松地将列表或向量的元素更改为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个回答

1
我们可以构建以下函数:
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)

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