如何操作嵌套列表中的NULL元素?

Ric*_*ton 16 r list

我有一个包含NULL元素的嵌套列表,我想用其他东西替换它们.例如:

l <- list(
  NULL,
  1,
  list(
    2,
    NULL,
    list(
      3,
      NULL
    )
  )
)
Run Code Online (Sandbox Code Playgroud)

我想用NA替换NULL元素.这样做的自然方法是使用递归循环遍历列表rapply.我试过了:

rapply(l, function(x) NA, classes = "NULL", how = "replace")
rapply(l, function(x) if(is.null(x)) NA else x, how = "replace")
Run Code Online (Sandbox Code Playgroud)

不幸的是,这些方法都不起作用,因为rapply显然忽略了NULL元素.

如何操作NULL嵌套列表中的元素?

Ric*_*ton 9

我要去"使用一个rapply不具有奇怪行为的版本NULL".这是我能想到的最简单的实现:

simple_rapply <- function(x, fn)
{
  if(is.list(x))
  {
    lapply(x, simple_rapply, fn)
  } else
  {
    fn(x)
  }
}
Run Code Online (Sandbox Code Playgroud)

(rawr::rapply2正如@rawr的评论中提到的那样是一种更复杂的尝试.)

现在我可以使用替换

simple_rapply(l, function(x) if(is.null(x)) NA else x)
Run Code Online (Sandbox Code Playgroud)


42-*_*42- 9

这就是William Dunlap在2010年提出的问题时提出的问题:Rhelp:

replaceInList <- function (x, FUN, ...) 
  {
      if (is.list(x)) {
          for (i in seq_along(x)) {
              x[i] <- list(replaceInList(x[[i]], FUN, ...))
          }
          x
      }
      else FUN(x, ...)
  }
 replaceInList(l, function(x)if(is.null(x))NA else x)
Run Code Online (Sandbox Code Playgroud)


Jon*_*oll 6

这是一个 hack,但就 hack 而言,我想我对它有些满意。

lna <- eval(parse(text = gsub("NULL", "NA", deparse(l))))

str(lna)
#> List of 3
#> $ : logi NA
#> $ : num 1
#> $ :List of 3
#> ..$ : num 2
#> ..$ : logi NA
#> ..$ :List of 2
#> .. ..$ : num 3
#> .. ..$ : logi NA
Run Code Online (Sandbox Code Playgroud)

更新:

如果由于某种原因您需要"NULL"作为列表中的字符条目(角情况,很多?)您仍然可以使用上面的 hack 因为它替换了字符串的内容,而不是引号,因此它只需要另一个步骤

l2 <- list(
  NULL,
  1,
  list(
    2,
    "NULL",
    list(
      3,
      NULL
    )
  )
)

lna2   <- eval(parse(text = gsub("NULL", "NA", deparse(l2))))
lna2_2 <- eval(parse(text = gsub('\\"NA\\"', '\"NULL\"', deparse(lna2))))

str(lna2_2)
#> List of 3
#> $ : logi NA
#> $ : num 1
#> $ :List of 3
#> ..$ : num 2
#> ..$ : chr "NULL"
#> ..$ :List of 2
#> .. ..$ : num 3
#> .. ..$ : logi NA 
Run Code Online (Sandbox Code Playgroud)

  • 看到这种将 R 转换为宏处理器的努力很有趣。不是“坏”,只是有趣。 (2认同)

sha*_*yaa 5

我将替换包包裹在sapply内,这使它对我更具可读性/可理解性,尽管通用性较低。

 replace_null <- function(x) {
  lapply(x, function(x) {
    if (is.list(x)){
      replace_null(x)
      } else{
        if(is.null(x)) NA else(x)
      } 
    })
}

replace_null(l)
Run Code Online (Sandbox Code Playgroud)