Comment parsingr XML vers R frame de données

J’ai essayé d’parsingr XML vers R frame de données, ce lien m’a beaucoup aidé:

Comment créer un bloc de données R à partir d’un fichier xml

Mais je n’étais toujours pas capable de comprendre mon problème:

Voici mon code:

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"")] 

La trame de données que je veux avoir est comme ceci:

 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 

Je suis coincé au xmlToDataFrame() , toute aide serait très appréciée, merci.

Les données au format XML sont rarement organisées de manière à permettre à la fonction xmlToDataFrame fonctionner. Il est préférable d’extraire tout ce qui se trouve dans les listes, puis de lier les listes ensemble dans un bloc de données:

 require(XML) data < - xmlParse("http://forecast.weather.gov/MapClick.php?lat=29.803&lon=-82.411&FcstType=digitalDWML") xml_data <- xmlToList(data) 

Dans le cas de vos données d'exemple, obtenir l'emplacement et l'heure de début est assez simple:

 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"]) 

Les données de température sont un peu plus compliquées. Vous devez d'abord accéder au nœud contenant les listes de températures. Ensuite, vous devez extraire les deux listes, regarder à l'intérieur de chacune et choisir celle qui a "hourly" comme l'une de ses valeurs. Ensuite, vous devez sélectionner uniquement cette liste, mais ne conserver que les valeurs qui ont le libellé "value":

 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 

Utilisez xpath plus directement pour la performance et la clarté.

 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")) 

menant à

 > 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 

Voici une solution partielle utilisant xml2. Briser la solution en morceaux plus petits permet généralement de s’assurer que tout est aligné:

 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() 

Vous pouvez essayer le code ci-dessous:

 # 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)