dat=list(list(id = "T"), list(id = "T"),
structure(list(NULL), names = NA_character_), list(id = "T"),
list(id = "T"), list(id = "T"))
unlist(dat)
我试过了,但没有奏效
dat[sapply(dat, is.null)] <- NA
dat=list(list(id = "T"), list(id = "T"),
structure(list(NULL), names = NA_character_), list(id = "T"),
list(id = "T"), list(id = "T"))
unlist(dat)
我试过了,但没有奏效
dat[sapply(dat, is.null)] <- NA
您应该将answerby ThomasIsCoding与上面的列表一起使用,其中顶层没有NULL
,并且不想递归地取消列出.
但是,如果这两个条件中的任何一个都不满足,则可以遍历列表,将NULL
设置为NA
.
tidyverse
approach对于这样的操作,我喜欢使用purrr::modify_tree()
,传递一个应用于每个叶的函数.
dat |>
purrr::modify_tree(
leaf = \(x) if(is.null(x)) NA else x,
post = unlist
)
# id id <NA> id id id
# "T" "T" NA "T" "T" "T"
post
参数是applied on the way "up", i.e. after the leaves are transformed的函数.
感觉好像您应该能够使用base::rapply()
来递归迭代.不幸的是,它是ignores NULL
elements.我们可以改为编写一个递归函数:
replace_null <- function(x, repl = NA, is_node = is.list) {
if(is_node(x)) return(lapply(x, replace_null))
if(is.null(x)) repl else x # or in R 4.4: x %||% repl
}
unlist(replace_null(dat))
# id id <NA> id id id
# "T" "T" NA "T" "T" "T"
is_node
参数确定是否进一步递归,方法与purrr::modify_tree()
中同名的参数相同.
%||%
顺便说一句,如果您正在使用R的当前开发版本(将作为4.4发布),您可以使用null coalescing operator.
L %||% R
New in base是短语if(!is.null(L)) L else R
或if(is.null(L)) R else L
的一个富有表现力的习语.
以下是当顶层项目之一为NULL
时这种方法的差异的示例.
l <- list(1, NULL)
unlist(l)
# [1] 1
dat |>
purrr::modify_tree(
leaf = \(x) x %||% NA,
post = unlist
)
# [1] 1 NA