Как анализировать XML-данные
Я попытался разобрать XML-фрейм данных R, эта ссылка мне очень помогла:
как создать кадр данных R из XML файла
Но все же я не смог понять свою проблему:
Вот мой код:
data <- xmlParse("http://forecast.weather.gov/MapClick.php?lat=29.803&lon=-82.411&FcstType=digitalDWML")
xmlToDataFrame(nodes=getNodeSet(data1,"//data"))[c("location","time-layout")]
step1 <- xmlToDataFrame(nodes=getNodeSet(data1,"//location/point"))[c("latitude","longitude")]
step2 <- xmlToDataFrame(nodes=getNodeSet(data1,"//time-layout/start-valid-time"))
step3 <- xmlToDataFrame(nodes=getNodeSet(data1,"//parameters/temperature"))[c("type="hourly"")]
Кадр данных, который я хочу иметь, выглядит следующим образом:
latitude longitude start-valid-time hourly_temperature
29.803 -82.411 2013-06-19T15:00:00-04:00 91
29.803 -82.411 2013-06-19T16:00:00-04:00 90
Я застрял в xmlToDataFrame, любая помощь будет очень оценена, спасибо.
Ответы
Ответ 1
Данные в формате XML редко организованы таким образом, чтобы функция xmlToDataFrame
работала. Вам лучше извлечь все в списках, а затем связать списки вместе в кадре данных:
require(XML)
data <- xmlParse("http://forecast.weather.gov/MapClick.php?lat=29.803&lon=-82.411&FcstType=digitalDWML")
xml_data <- xmlToList(data)
В случае ваших данных примера получение местоположения и время запуска довольно просто:
location <- as.list(xml_data[["data"]][["location"]][["point"]])
start_time <- unlist(xml_data[["data"]][["time-layout"]][
names(xml_data[["data"]][["time-layout"]]) == "start-valid-time"])
Данные температуры немного сложнее. Сначала вам нужно добраться до node, который содержит списки температур. Затем вам нужно извлечь оба списка, посмотреть в каждом из них и выбрать тот, который имеет "почасовое" значение в качестве одного из его значений. Затем вам нужно выбрать только этот список, но только сохранить значения, имеющие метку "значение":
temps <- xml_data[["data"]][["parameters"]]
temps <- temps[names(temps) == "temperature"]
temps <- temps[sapply(temps, function(x) any(unlist(x) == "hourly"))]
temps <- unlist(temps[[1]][sapply(temps, names) == "value"])
out <- data.frame(
as.list(location),
"start_valid_time" = start_time,
"hourly_temperature" = temps)
head(out)
latitude longitude start_valid_time hourly_temperature
1 29.81 -82.42 2013-06-19T16:00:00-04:00 91
2 29.81 -82.42 2013-06-19T17:00:00-04:00 90
3 29.81 -82.42 2013-06-19T18:00:00-04:00 89
4 29.81 -82.42 2013-06-19T19:00:00-04:00 85
5 29.81 -82.42 2013-06-19T20:00:00-04:00 83
6 29.81 -82.42 2013-06-19T21:00:00-04:00 80
Ответ 2
Используйте xpath более прямо как для производительности, так и для ясности.
time_path <- "//start-valid-time"
temp_path <- "//temperature[@type='hourly']/value"
df <- data.frame(
latitude=data[["number(//point/@latitude)"]],
longitude=data[["number(//point/@longitude)"]],
start_valid_time=sapply(data[time_path], xmlValue),
hourly_temperature=as.integer(sapply(data[temp_path], as, "integer"))
приводящий к
> head(df, 2)
latitude longitude start_valid_time hourly_temperature
1 29.81 -82.42 2014-02-14T18:00:00-05:00 60
2 29.81 -82.42 2014-02-14T19:00:00-05:00 55
Ответ 3
Здесь частичное решение с использованием xml2. Разрушение решения на более мелкие куски обычно упрощает обеспечение выстраивания всей конструкции:
library(xml2)
data <- read_xml("http://forecast.weather.gov/MapClick.php?lat=29.803&lon=-82.411&FcstType=digitalDWML")
# Point locations
point <- data %>% xml_find_all("//point")
point %>% xml_attr("latitude") %>% as.numeric()
point %>% xml_attr("longitude") %>% as.numeric()
# Start time
data %>%
xml_find_all("//start-valid-time") %>%
xml_text()
# Temperature
data %>%
xml_find_all("//temperature[@type='hourly']/value") %>%
xml_text() %>%
as.integer()
Ответ 4
Вы можете попробовать код ниже:
# Load the packages required to read XML files.
library("XML")
library("methods")
# Convert the input xml file to a data frame.
xmldataframe <- xmlToDataFrame("input.xml")
print(xmldataframe)