Ошибка пакета XML в 2.12, но не в 2.10 - PullRequest
1 голос
/ 03 февраля 2011

Я использую пакет XML в R для чтения таблиц HTML со страницы.В 2.12.1 я получаю следующую ошибку:

Error in names(ans) = header : 
  'names' attribute [24] must be the same length as the vector [19]

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

Вот мой код:

## load the libraries
library(XML)

## set the season
SEASON <- "2011"

## create the URL
URL <- paste("http://www.hockey-reference.com/leagues/NHL_", SEASON, "_goalies.html", sep="")

## grab the page -- the table is parsed nicely -- why work 2.10, but not 2.12.1?
tables <- readHTMLTable(URL)
* 1008высоко ценится.

1 Ответ

1 голос
/ 04 февраля 2011

Я не уверен, возникает ли эта проблема из-за перехода на v2.12.1 или нет.Я попробовал это на 2.12.1 и получил ту же ошибку.

Однако ошибка может также произойти, потому что что-то в HTML изменилось.Я посмотрел на источник HTML на этой странице, и таблица не так хорошо сформирована, как можно было бы надеяться.С таблицей HTML есть две проблемы: 1) первая строка заголовка содержит объединенные столбцы, и 2) строка заголовка повторяется.

Это первая из них, которая приводит к тому, что ваш код возвращает ошибку.Строки данных имеют длину 19, но заголовок состоит из двух строк, одна из которых имеет длину 19, а другая - длину 5, т.е. всего 24.Именно это несоответствие приводит к вашей ошибке.

Я не смог очистить эту страницу с помощью функции readHTMLTable ().Но вот мое решение с использованием инструментов scrapeR и XML:

# load the libraries
library(XML)
library(scrapeR)
library(plyr)
library(stringr)

# scrape and parse page
page <- scrape(url=URL, parse=TRUE)
raw <- xpathSApply(page[[1]], "//table//tr", xmlValue)
# split strings at each line break
rows <- strsplit(raw, "\n")
# now check for longest row length, and discard all short rows
rowlength <- (laply(rows, length))
rows <- rows[rowlength==max(rowlength)]
# unlist each row
rows <- laply(rows, function(x)unlist(x))
# trim white space
rows <- aaply(rows, c(1,2), str_trim)
# convert to data frame
df <- as.data.frame(rows, stringsAsFactors = FALSE)
# read names from first row
names(df) <- laply(df[1, ], str_trim)
# remove all rows without a numerix index
df <- df[which(!is.na(as.numeric(df$Rk))), ]
df

Код немного запутан, и таблица не чистая, так как все данные являются символьными векторами, а нечисловой.

Но по крайней мере это означает, что у вас есть данные в формате, который вы можете обрабатывать дальше.

...