重构任意嵌套列表
Restructuring an arbitrarily nested list
我有一个结构如下的列表:
l <- list(condition = "AND",
rules = list(list(id = "sex",
field = "sex"),
list(condition = "AND",
rules = list(
list(id = "species",
field = "species"),
list(condition = "AND",
rules = list(
list(id = "bill_length_mm",
field = "bill_length_mm")))))),
valid = TRUE)
我想转换成这个结构
goal <- list(
list(id = "sex",
field = "sex"),
list(id = "species",
field = "species"),
list(id = "bill_length_mm",
field = "bill_length_mm")
)
解决方案需要足够灵活以处理 more/less rules
元素。非常感谢任何关于我如何做到这一点的建议!
使用递归函数 rrapply
library(rrapply)
out <- rrapply(l, condition = function(x, .xname)
.xname %in% c('id', 'field'), how = "flatten" )
out2 <- unname(split(as.list(out), cumsum(names(out) == "id")) )
-检查预期输出
> identical(goal, out2)
[1] TRUE
或者如评论中提到的@Joris C.
out <- rrapply(l, classes = "list", condition =
function(x) "id" %in% names(x), how = "flatten")
names(out) <- NULL
看来你可以在这里使用递归策略。这将查找具有 id
元素的列表,并将 return 它们作为列表。
get_fields <- function (x) {
if (is.list(x)) {
if (!is.null(x$id)) {
return(list(x))
} else {
unname(do.call("c", lapply(x, get_fields)))
}
} else {
NULL
}
}
dput(result<-get_fields(l))
# list(list(id = "sex", field = "sex"), list(id = "species", field = "species"),
# list(id = "bill_length_mm", field = "bill_length_mm"))
我有一个结构如下的列表:
l <- list(condition = "AND",
rules = list(list(id = "sex",
field = "sex"),
list(condition = "AND",
rules = list(
list(id = "species",
field = "species"),
list(condition = "AND",
rules = list(
list(id = "bill_length_mm",
field = "bill_length_mm")))))),
valid = TRUE)
我想转换成这个结构
goal <- list(
list(id = "sex",
field = "sex"),
list(id = "species",
field = "species"),
list(id = "bill_length_mm",
field = "bill_length_mm")
)
解决方案需要足够灵活以处理 more/less rules
元素。非常感谢任何关于我如何做到这一点的建议!
使用递归函数 rrapply
library(rrapply)
out <- rrapply(l, condition = function(x, .xname)
.xname %in% c('id', 'field'), how = "flatten" )
out2 <- unname(split(as.list(out), cumsum(names(out) == "id")) )
-检查预期输出
> identical(goal, out2)
[1] TRUE
或者如评论中提到的@Joris C.
out <- rrapply(l, classes = "list", condition =
function(x) "id" %in% names(x), how = "flatten")
names(out) <- NULL
看来你可以在这里使用递归策略。这将查找具有 id
元素的列表,并将 return 它们作为列表。
get_fields <- function (x) {
if (is.list(x)) {
if (!is.null(x$id)) {
return(list(x))
} else {
unname(do.call("c", lapply(x, get_fields)))
}
} else {
NULL
}
}
dput(result<-get_fields(l))
# list(list(id = "sex", field = "sex"), list(id = "species", field = "species"),
# list(id = "bill_length_mm", field = "bill_length_mm"))