Разбор HTML-таблиц с использованием пакетов XML / RCurl R без использования функции readHTMLTable - PullRequest
3 голосов
/ 21 июня 2011

Я пытаюсь очистить / извлечь данные из одной HTML-таблицы: http://www.theplantlist.org/tpl/record/kew-419248 и нескольких очень похожих страниц. Сначала я попытался использовать следующую функцию для чтения таблицы, но она не была идеальной, потому что я хочу разделить название каждого вида на составные части (род / вид / инфрасвид / автор и т. Д.).

library(XML)
readHTMLTable("http://www.theplantlist.org/tpl/record/kew-419248")

Я использовал SelectorGadget, чтобы идентифицировать уникальный XPATH для каждого элемента таблицы, который я хочу извлечь (не обязательно самый короткий):

Для имен родов: // [содержит (concat ("", @class, ""), concat ("", "Synonym", ""))] // [содержит (concat ("", @class, ""), concat ("", "род", ""))]

Для названий видов: // [содержит (concat ("", @class, ""), concat ("", "Synonym", ""))] // [содержит (concat ("", @class, ""), concat ("", "разновидности", ""))]

Для внутривидовых рангов: // * [содержит (concat ("", @class, ""), concat ("", "infraspr", ""))]]

Для названий внутривидов: // * [содержит (concat ("", @class, ""), concat ("", "infraspe", ""))]]

Для уровней достоверности (изображение): // [содержит (concat ("", @class, ""), concat ("", "synonyms", ""))]] // img Для источников: // [содержит (concat ("", @class, ""), concat ("", "source", ""))] // a

Теперь я хочу извлечь информацию в фрейм данных / таблицу.

Я попытался использовать функцию xpathSApply пакета XML для извлечения некоторых из этих данных:

например. по внутривидовым разрядам

library(XML)
library(RCurl)
infraspeciesrank = htmlParse(getURL("http://www.theplantlist.org/tpl/record/kew-419248"))
path=' //*[contains(concat( " ", @class, " " ), concat( " ", "infraspr", " " ))]'
xpathSApply(infraspeciesrank, path)

Однако этот метод проблематичен из-за пробелов в данных (например, только некоторые строки таблицы имеют ранг внутривидовой принадлежности, поэтому все, что я возвратил, это список трех рангов в таблице без пробелов). Вывод данных также относится к классу, который у меня возникла проблема с подключением к кадру данных.

Кто-нибудь знает лучший способ извлечения информации из этой таблицы в информационный кадр?

Любая помощь будет высоко ценится!

Tom

Ответы [ 2 ]

5 голосов
/ 21 июня 2011

Вот еще одно решение, которое разбивает название каждого вида на составные части

library(XML)
library(plyr)

# read url into html tree
url = "http://www.theplantlist.org/tpl/record/kew-419248"
doc = htmlTreeParse(url, useInternalNodes = T)

# extract nodes containing desired information
xp_expr = "//table[@class= 'names synonyms']/tbody/tr"
nodes = getNodeSet(doc, xp_expr)

# function to extract desired fields from a given node    
fields = list('genus', 'species', 'infraspe', 'authorship')
read_node = function(node){

    dl = lapply(fields, function(x) xpathSApply(node, 
       paste(".//*[@class = ", "'", x, "'", "]", sep = ""), xmlValue))
    tmp = rep(' ', length(dl))
    tmp[sapply(dl, length) == 1] = unlist(dl)
    confidence = xpathSApply(node, './/img', xmlGetAttr, 'alt')
    return(c(tmp, confidence))
}

# apply function to all nodes and return data frame
df = ldply(nodes, read_node)
names(df) = c(fields, 'confidence')

Создает следующий вывод

 genus      species     infraspe                      authorship confidence
1 Critesion     chilense              (Roem. & Schult.) Ã\u0081.Löve          H
2   Hordeum     chilense     chilense                                          L
3   Hordeum  cylindricum                                       Steud.          H
4   Hordeum depauperatum                                       Steud.          H
5   Hordeum     pratense brongniartii                       Macloskie          L
6   Hordeum    secalinum     chilense                   Ã\u0089.Desv.          L
2 голосов
/ 21 июня 2011

Следующий код анализирует вашу таблицу в матрицу.

Предостережения:

  • Столбец уровня достоверности пуст, поскольку это не текст, а изображение. Если это важно, вы сможете найти местоположение изображения и проанализировать его.
  • Есть некоторые проблемы с кодировкой (символ UTF-8 конвертируется в ASCII на моем компьютере). Я пока не знаю, как это исправить.

код:

library(XML)
library(RCurl)

baseURL <- "http://www.theplantlist.org/tpl/record/kew-419248"
txt <- getURL(url=baseURL)

xmltext <- htmlParse(txt, asText=TRUE)
xmltable <- xpathApply(xmltext, "//table//tbody//tr")
t(sapply(xmltable, function(x)unname(xmlSApply(x, xmlValue))[c(1, 3, 5, 7)]))

Результаты:

     [,1]                                                [,2]      [,3] [,4]  
[1,] "Critesion chilense (Roem. & Schult.) Ã.Löve" "Synonym" ""   "WCSP"
[2,] "Hordeum chilense var. chilense "                   "Synonym" ""   "TRO" 
[3,] "Hordeum cylindricum Steud. [Illegitimate]"         "Synonym" ""   "WCSP"
[4,] "Hordeum depauperatum Steud."                       "Synonym" ""   "WCSP"
[5,] "Hordeum pratense var. brongniartii Macloskie"      "Synonym" ""   "WCSP"
[6,] "Hordeum secalinum var. chilense Ã.Desv."        "Synonym" ""   "WCSP"
...