5

我有一个像这样的 html 和 R 代码,需要将每个节点值与 data.frame 中的父 ID 相关联。每个人都有一些不同的信息。

example <- "<div class='person' id='1'>
<div class='phone'>555-5555</div>
<div class='email'>jhon@123.com</div>
</div>
<div class='person' id='2'>
<div class='phone'>123-4567</div>
<div class='email'>maria@gmail.com</div>
</div>
<div class='person' id='3'>
<div class='phone'>987-6543</div>
<div class='age'>32</div>
<div class='city'>New York</div>
</div>"

doc = htmlTreeParse(example, useInternalNodes = T)

values <- xpathSApply(doc, "//*[@class='person']/div", xmlValue)
variables <- xpathSApply(doc, "//*[@class='person']/div", xmlGetAttr, 'class')
id <- xpathSApply(doc, "//*[@class='person']", xmlGetAttr, 'id')

# The problem: create a data.frame(id,variables,values)

使用xpathSApply(),我也可以获得电话、电子邮件和年龄值以及人员属性 (id)。但是,这些信息是孤立的,我需要将它们引用到正确的 data.frame 变量和正确的人。在我的真实数据中有很多不同的信息,所以这个命名每个变量的过程必须是自动的。

我的目标是创建一个像这样的 data.frame,将每个 id 与其适当的数据相关联。

  id variables          values
1  1     phone        555-5555
2  1     email    jhon@123.com
3  2     phone        123-4567
4  2     email maria@gmail.com
5  3     phone        987-6543
6  3       age              32
7  3      city        New York

我相信我必须创建一个在内部使用的函数,该函数xpathSApply将同时获得人员电话和人员 ID,因此它们是相关的,但到目前为止我还没有取得任何成功。

谁能帮我?

4

1 回答 1

8

一般来说,这并不容易:

idNodes <- getNodeSet(doc, "//div[@id]")
ids <- lapply(idNodes, function(x) xmlAttrs(x)['id'])
values <- lapply(idNodes, xpathApply, path = './div[@class]', xmlValue)
attributes <- lapply(idNodes, xpathApply, path = './div[@class]', xmlAttrs)
do.call(rbind.data.frame, mapply(cbind, ids, values, attributes))
  V1              V2    V3
1  1        555-5555 phone
2  1    jhon@123.com email
3  2        123-4567 phone
4  2 maria@gmail.com email
5  3        987-6543 phone
6  3              32   age
7  3        New York  city

以上将为您提供属性和值对,假设它们嵌套在div带有关联的id.

更新:如果您想将其包装在 xpathApply 类型调用中

utilFun <- function(x){
  id <- xmlGetAttr(x, 'id')
  values <- sapply(xmlChildren(x, omitNodeTypes = "XMLInternalTextNode"), xmlValue)
  attributes <- sapply(xmlChildren(x, omitNodeTypes = "XMLInternalTextNode"), xmlAttrs)
  data.frame(id = id, attributes = attributes, values = values, stringsAsFactors = FALSE)
}
res <- xpathApply(doc, '//div[@id]', utilFun)
do.call(rbind, res)
  id attributes          values
1  1      phone        555-5555
2  1      email    jhon@123.com
3  2      phone        123-4567
4  2      email maria@gmail.com
5  3      phone        987-6543
6  3        age              32
7  3       city        New York
于 2013-08-13T21:59:48.843 回答