XML को R डेटा फ्रेम में पार्स कैसे करें


103

मैंने XML को 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(), किसी भी मदद की बहुत सराहना की जाएगी, धन्यवाद।

जवाबों:


103

एक्सएमएल प्रारूप में डेटा शायद ही कभी एक तरह से व्यवस्थित होता है जो 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"])

तापमान डेटा थोड़ा अधिक जटिल है। सबसे पहले आपको उस नोड पर जाना होगा जिसमें तापमान सूचियां होती हैं। फिर आपको दोनों सूचियों को निकालने की आवश्यकता है, प्रत्येक के भीतर देखें, और उस एक को चुनें जिसे "प्रति घंटा" उसके मूल्यों में से एक के रूप में है। फिर आपको केवल उस सूची का चयन करने की आवश्यकता है लेकिन केवल उन मानों को रखें जिनके पास "मान" लेबल है:

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

94

प्रदर्शन और स्पष्टता दोनों के लिए 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

12
यह वास्तव में स्वीकृत उत्तर होना चाहिए। यह अधिक संक्षिप्त है और सूचियों की तुलना में xpath का प्रदर्शन बेहतर है।
13

39

यहाँ एक आंशिक समाधान 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()

8
मददगार जवाब। अगर कोई और इसके पार जाता है, तो यहां एक ट्यूटोरियल का लिंक हैडली द्वारा xml2 का उपयोग करके: blog.rstudio.com/2015/04/21/xml2
रिचर्ड एरिकसन

9

आप नीचे दिए गए कोड को आज़मा सकते हैं:

# 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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.