使用类似于xpath的方法访问R中的列表元素

kupeojn6  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(163)

我在R中有下面的列表,名为l(在本例中,我从XML创建它,但我的真实的示例来自不同的源):

library(xml2)
x <- read_xml("
  <foo> 
    <bar> <baz>apple</baz> <faz>cat</faz> </bar> 
    <bar> <baz>orange</baz> <faz>dog</faz> </bar> 
  </foo>")
l <- as_list(x)

l
$foo
$foo$bar
$foo$bar$baz
$foo$bar$baz[[1]]
[1] "apple"

$foo$bar$faz
$foo$bar$faz[[1]]
[1] "cat"

$foo$bar
$foo$bar$baz
$foo$bar$baz[[1]]
[1] "orange"

$foo$bar$faz
$foo$bar$faz[[1]]
[1] "dog"

我需要从这个列表中提取所有的baz元素。如果我有XML格式的数据,我可以很简单地使用xml2来完成这个任务:

x |> xml_find_all("//faz") |> xml_text()
[1] "cat" "dog"
<faz>

但是我在R中看到的解决方案通常需要复杂的lapply()组合,这让我头疼:-)
有没有办法以类似的方式访问一般R列表中的元素?我并不拘泥于xpath语法本身,我很乐意找到一个解决方案,可以将任意列表扁平化为类似于/foo/bar/baz的路径名称,然后使用grep()或类似方法进行搜索,例如:

names_as_paths(l) |> str_subset("/baz") |> extract_by_path(l)
u5rb5r59

u5rb5r591#

查看受this answer启发的递归函数:

get_elements <- function(x, element) {
  if(is.list(x))
  {
    if(element %in% names(x)) x[[element]]
    else unname(unlist(lapply(x, get_elements, element = element)))
  }
}

get_elements(l, "faz")
#[1] "cat" "dog"
b1uwtaje

b1uwtaje2#

如果我理解正确的话,简单地应用unlist就足够了:

L <- unlist(l) 
L
#> foo.bar.baz foo.bar.faz foo.bar.baz foo.bar.faz 
#>    "apple"       "cat"    "orange"       "dog" 

L[grep("baz",names(L))]
#> foo.bar.baz foo.bar.baz
#>    "apple"    "orange"

相关问题