从嵌套列表中按名称提取元素 [英] Extract elements by name from a nested list

查看:55
本文介绍了从嵌套列表中按名称提取元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于命名的嵌套列表,提取特定元素的最佳方法是什么?如果我有一个包含已知字段的列表(例如,来自yaml文件),我想提取一个元素(列表或其他形式),而不必搜索名称和索引或尝试跟踪中的级别str 输出.

For a named, nested list, what is the best way to extract a specific element? If I have a list with known fields (eg, from a yaml file), I want to extract an element (list or otherwise) without having to search through the names and indices or trying to keep track of the levels in the str output.

例如,我知道 lm 返回一个包含 qr 信息的嵌套列表.

For example, I know that lm returns a nested list which contains qr info.

fit <- lm(mpg ~ wt, mtcars)
fit$qr$qraux
# [1] 1.176777 1.046354

但是,如果我不知道顺序,我只想指定列表以及元素名称.理想情况下,某些东西既可以给我元素的索引路径,又可以给元素元素本身的名称路径.

But if I don't know the order, I just want to specify the list along with the name of the element. Ideally, something would give me both the path of indices to the element and path of names to the element and the element itself.

相关相关推荐答案

我的递归版本1开始出现比我最初想的还要多的错误,因此我采取了一种简便的方法,基本上是捕获了 utils的捕获输出.::: print.ls_str (我认为).

My recursive version 1 started to get more buggy than I first thought, so I took an easy way out and am basically grepping the captured output of utils:::print.ls_str (I think).

到目前为止,这至少有两个缺点:捕获的输出和eval-parse-texting,但是对于诸如 ggplot2 :: ggplotGrob 这样的非常嵌套的列表,它似乎可以正常工作.

This has at least two disadvantages so far: captured output and eval-parse-texting, but it seems to work correctly for a very nested list such as in ggplot2::ggplotGrob.

这些只是一些辅助功能

unname2 <- function(l) {
  ## unname all lists
  ## str(unname2(lm(mpg ~ wt, mtcars)))
  l <- unname(l)
  if (inherits(l, 'list'))
    for (ii in seq_along(l))
      l[[ii]] <- Recall(l[[ii]])
  l
}

lnames <- function(l) {
  ## extract all list names
  ## lnames(lm(mpg ~ wt, mtcars))
  nn <- lpath(l, TRUE)
  gsub('\\[.*', '', sapply(strsplit(nn, '\\$'), tail, 1))
}

lpath <- function(l, use.names = TRUE) {
  ## return all list elements with path as character string
  ## l <- lm(mpg ~ wt, mtcars); lpath(l); lpath(l, FALSE)
  ln <- deparse(substitute(l))
  # class(l) <- NULL
  l <- rapply(l, unclass, how = 'list')
  L <- capture.output(if (use.names) l else unname2(l))
  L <- L[grep('^\\$|^[[]{2,}', L)]
  paste0(ln, L)
}

这是返回有用的信息

lextract <- function(l, what, path.only = FALSE) {
  # stopifnot(what %in% lnames(l))
  ln1 <- eval(substitute(lpath(.l, TRUE), list(.l = substitute(l))))
  ln2 <- eval(substitute(lpath(.l, FALSE), list(.l = substitute(l))))
  cat(ln1[idx <- grep(what, ln1)], sep = '\n')
  cat('\n')
  cat(ln2[idx], sep = '\n')
  cat('\n')
  if (!path.only)
    setNames(lapply(idx, function(x) eval(parse(text = ln1[x]))), ln1[idx])
  else invisible()
}

fit <- lm(mpg ~ wt, mtcars)
lextract(fit, 'qraux')
# fit$qr$qraux
# 
# fit[[7]][[2]]
# 
# [1] 1.176777 1.046354

所以我可以直接使用该返回值,或者现在我有了索引.

So I can use that return value directly or now I have the indices.

fit[[7]][[2]]
# [1] 1.176777 1.046354


## etc
lextract(fit, 'qr', TRUE)

# fit$qr
# fit$qr$qr
# fit$qr$qraux
# fit$qr$pivot
# fit$qr$tol
# fit$qr$rank
# 
# fit[[7]]
# fit[[7]][[1]]
# fit[[7]][[2]]
# fit[[7]][[3]]
# fit[[7]][[4]]
# fit[[7]][[5]]

但是,我更喜欢内置式或单线式.

I would prefer a built-in or one-liner, however.

这篇关于从嵌套列表中按名称提取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆