xml - con - xpath list of elements
R: ¿Cómo obtener atributos padre y valores de nodo en el momento del sitio? (1)
Tengo un html y un código R como estos y necesito relacionar cada valor de nodo con su id principal en un data.frame. Hay información diferente disponible para cada persona.
example <- "<div class=''person'' id=''1''>
<div class=''phone''>555-5555</div>
<div class=''email''>[email protected]</div>
</div>
<div class=''person'' id=''2''>
<div class=''phone''>123-4567</div>
<div class=''email''>[email protected]</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)
Con xpathSApply()
, puedo obtener los valores de teléfono, correo electrónico y edad, así como los atributos de persona (id) también. Sin embargo, esa información se aísla y necesito hacer referencia a la variable correcta data.frame y a la persona adecuada. En mis datos reales hay mucha información diferente, por lo que este proceso de denominación de cada variable debe ser automático.
Mi objetivo es crear un marco de datos como este que relacione cada identificación con sus datos correctos.
id variables values
1 1 phone 555-5555
2 1 email [email protected]
3 2 phone 123-4567
4 2 email [email protected]
5 3 phone 987-6543
6 3 age 32
7 3 city New York
Creo que tendría que crear una función para usar dentro de xpathSApply
que obtenga al mismo tiempo el teléfono de la persona y la identificación de la persona, para que estén relacionados, pero hasta ahora no he tenido éxito.
¿Alguien puede ayudarme?
En general, no va a ser fácil:
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 [email protected] email
3 2 123-4567 phone
4 2 [email protected] email
5 3 987-6543 phone
6 3 32 age
7 3 New York city
Lo anterior le dará los pares de atributos y valores asumiendo que están anidados en un div
con un id
. Asociado.
ACTUALIZACIÓN: si desea envolverlo en una llamada de tipo 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 [email protected]
3 2 phone 123-4567
4 2 email [email protected]
5 3 phone 987-6543
6 3 age 32
7 3 city New York