Я новичок в пакете xml для r и новичок в xpath. У меня есть очень большой xml-файл, который я анализирую. Я написал некоторый код с использованием циклов, который работает, но занимает слишком много времени, поэтому я пишу более эффективный код, используя xpath. xml выглядит примерно так:
...
<person personId="1">
<personNames>
<personName nameId="1000">
<first>Joe<last>
<last>Jones<last>
</personName>
<personName nameId="1001">
<first>Joseph><first>
<last>Jones<last>
</personName>
<personName nameId="1002"
<first>The One and only Joe<first>
</personName>
</personNames>
</person>
...
У кого-то одно имя, у кого-то другое. У кого-то есть имя и фамилия, у кого-то только имя или только фамилия. Итак, мне нужно быть осторожным.
Мне удалось эффективно создать фрейм данных с именами и фамилиями, используя xpath:
library(XML)
doc<-xmlTreeParse("People.xml",useInternalNodes = TRUE)
top<-xmlRoot(doc)
First<-as.character(xpathApply(top,"//person/personNames/personName/first", xmlValue))
name_id<-as.integer(xpathApply(top,"//person/personNames/personName[first]/@nameId"))
FirstNames<-data.frame(TMS_name_id=name_id,first=First)
Last<-as.character(xpathApply(top,"//person/personNames/personName/last", xmlValue))
name_id<-as.integer(xpathApply(top,"//person/personNames/personName[last]/@nameId"))
LastNames<-data.frame(name_id=name_id,last=Last)
Names<-merge(x=FirstNames,y=LastNames,by="name_id",all=TRUE)
Фрейм данных My Names выглядит хорошо. Он имеет nameId, имя и фамилию каждого человека. Если имя или фамилия отсутствуют, это значение равно null. Он сгенерирован за несколько минут (610 тысяч строк!). Потрясающий.
Проблема заключается в том, чтобы связать эти имена с родительским personId. Я предполагаю, что мне нужно перебрать имена в моем фрейме данных и получить идентификатор человека с правильным атрибутом nameId, но я не могу этого сделать. Например, следующий код дает мне нулевой результат:
xpathSApply(top,"//person/personNames/personName[@nameId="1000"]/@personId")
Я ожидаю результата 1. Каков наиболее эффективный способ добавить столбец в мой фрейм данных для personId?
Учитывая приведенный выше пример, я хочу, чтобы фрейм данных выглядел следующим образом:
nameId first last personId
1000 Joe Jones 1
1001 Joseph Jones 1
1002 The one and only Joe <NA> 1