如何访问复杂列表中的元素?

时间:2010-05-20 14:30:21

标签: r

我有一个不错的列表,如下所示:

tmp = NULL
t = NULL
tmp$resultitem$count = "1057230"
tmp$resultitem$status = "Ok"
tmp$resultitem$menu = "PubMed"
tmp$resultitem$dbname = "pubmed"
t$resultitem$count = "305215"
t$resultitem$status = "Ok"
t$resultitem$menu = "PMC"
t$resultitem$dbname = "pmc"
tmp = c(tmp, t)
t = NULL
t$resultitem$count = "1"
t$resultitem$status = "Ok"
t$resultitem$menu = "Journals"
t$resultitem$dbname = "journals"
tmp = c(tmp, t)

产生:

> str(tmp)
List of 3
 $ resultitem:List of 4
  ..$ count : chr "1057230"
  ..$ status: chr "Ok"
  ..$ menu  : chr "PubMed"
  ..$ dbname: chr "pubmed"
 $ resultitem:List of 4
  ..$ count : chr "305215"
  ..$ status: chr "Ok"
  ..$ menu  : chr "PMC"
  ..$ dbname: chr "pmc"
 $ resultitem:List of 4
  ..$ count : chr "1"
  ..$ status: chr "Ok"
  ..$ menu  : chr "Journals"
  ..$ dbname: chr "journals"

现在我想搜索每个resultitem的元素。 我想知道每个数据库的dbname,其数量少于10 count(示例)。 在这种情况下它很容易,因为这个列表只有3个元素,但真正的列表有点长。

这可以通过for循环完成。但有没有办法用R的其他功能(如rapply)做到这一点? 我对这些应用函数的问题是,它们只看一个元素。

如果我使用grep来获取所有dbname个元素,我就无法获得每个元素的计数。

rapply(tmp, function(x) paste("Content: ", x))[grep("dbname", names(rapply(tmp, c)))]

有人比for循环有更好的想法吗?

3 个答案:

答案 0 :(得分:5)

R一般都希望将这些东西作为data.frames来处理,所以我认为你最好的办法就是把你的列表变成一个(或者甚至创建一个data.frame而不是一个列表,除非你需要它以列表形式)。

x <- do.call(rbind,tmp)
dat <- data.frame(x)
dat$count <- as.numeric(dat$count)

> dat
    count status     menu   dbname
1 1057230     Ok   PubMed   pubmed
2  305215     Ok      PMC      pmc
3       1     Ok Journals journals

然后得到你的答案,你可以使用普通的data.frame子集操作:

> dat$dbname[dat$count<10]
$resultitem
[1] "journals"

答案 1 :(得分:2)

如果您绝对坚持必须在列表中执行此操作,则以下内容适用于本案例。

x <- tmp[sapply(tmp, function(x){x$count>10})]
str(x)
(the list items you wanted)

更一般地说,如果你想以这种方式实际使用不规则列表,你可以使用相同的代码,但首先检查项目的存在

testForCount <- function(x) {if ('count' %in% names(x)) x$count>10 else FALSE}
tmp[sapply (tmp, count)]

这适用于列表长度与本案例不同的情况。 (我仍然认为你应该使用数据帧来加速和合理地表示数据)。

答案 2 :(得分:0)

看起来您的列表来自XML结构。 使用XPath并使用NodeSet结构和功能更容易导航到您想要的内容 XML包中的getNodeSet