Parsowanie XMLa w R

Jak w R obsłużyć dane zapisane w XML?

Do redakcji ;-) przychodzą dziesiątki, jeśli nie setki ;-)) maili w których pytacie jak pobrałem dane z Veturilo, które wykorzystałem wiosną tego roku we wpisach jeden oraz dwa. Pobrałem je z pliku XML. Było to w PHP, ale da się też w R. Do obsługi XMLa jest oczywiście odpowiedni pakiet o jakże zaskakującej nazwie XML.

Zanim dojdziemy do Veturilo przećwiczymy obsługę XMLa na przykładzie kanału RSS (plik dla czytnika RSS jest również XMLem). Jeśli nie znasz składni XMLa warto o niej doczytać.

Za przykład niech posłuży RSS niniejszego bloga. getURL() z pakietu RCurl pobierze nam zawartość pliku (może to być też plik z dysku – wtedy można go wczytać na przykład przez read_lines() i skleić linie w jeden ciąg na przykład poprzez paste() z parametrem collapse = ""):

Mając ciąg znaków z zawartością pliku XML musimy go przetworzyć na odpowiedni obiekt, z którego będziemy wyłuskiwać interesujące nas dane.

Na początek zobaczmy jakie części mamy w korzeniu pliku:

Widać tylko jedną, zobaczmy co siedzi w środku:

Tutaj jest kilka elementów opisujących kanał RSS i sporo elementów typu item. Gdy otworzymy plik w jakimś notatniku czy nawet w przeglądarce łatwo zrozumiemy co jest czym. Zobaczmy co składa się (jakie pola) na obiekt typu item:

O! To jest mięsko które nas interesuje. Tu znajdziemy tytuł wpisu (title), link do niego (link), datę publikacji (pubDate) oraz treść (description).

Do wartości każdego z elementów możemy dotrzeć poprzez funkcję xmlValue(). Sprowadźmy więc wszystkie wartości elementów z obiektów typu item do ramki danych:

I gotowe! Prawda, że banalne? Wynik jest następujący:

title pubDate description link
Przez losowy las Spotify 2017-12-10 09:16:32 Czy machine learning może pomóc w poszukiwaniu ulubionej muzyki? Dzisiaj zajmiemy się poszukiwaniem nowej muzyki. Już kiedyś o tym było w oparciu o LastFM, dzisiaj będzie w oparciu o Spotify. Taki szybki wpis. Na początek potrzebujemy kilku elementów: własnej aplikacji współpracującej z API Spotify – zbudować ją można zaczynając z dashboardu Spotify, potrzebujemy numerku client_id … Czytaj dalej Przez losowy las Spotify http://blog.prokulski.science/index.php/2017/12/10/spotify-random-forest/
Analiza procesów 2017-12-02 08:27:35 W którym miejscu można skrócić proces, na której fazie trwa on najdłużej? Dzisiaj zajmiemy się analizą dowolnego procesu, w którym można wskazać jakieś fazy. Zadanie wzięło się z pracy, którą wykonuję na co dzień: który element procesu wytwórczego oprogramowania trwa najdłużej? Czy to, że przygotowanie systemu IT trwa tak długo to wina IT (analiza wymagań, … Czytaj dalej Analiza procesów http://blog.prokulski.science/index.php/2017/12/02/analiza-procesow/
Wino 2017-11-23 08:01:52 Jakie wina sprzedają się najlepiej? Czy Polacy lubią wino czerwone czy białe? Słodkie czy wytrawne? Jak wybrać wino dobre i tanie? Dane na potrzeby analizy pobierzemy ze sklepu internetowego. Odpowiedni skrypt (i pobrane dane) znajdziecie w repo na GitHubie, w pliku get_data.R. Skrypt jest dość długi, nie wnosi niczego ciekawego do samej analizy. Po zebraniu … Czytaj dalej Wino http://blog.prokulski.science/index.php/2017/11/23/wino/
Sondaże przedwyborcze 2017-11-17 13:36:51 Komu rośnie, a komu spada? Czy PSL przekroczy próg 5% i załapie się do Sejmu? Czy “totalna opozycja” już przegrywa z partią rządzącą czy jeszcze nie? Takie pytania rozgrzewają komentatorów polskiej sceny politycznej mniej więcej raz w tygodniu, przy okazji publikacji kolejnych sondaży przedwyborczych. Zajmiemy się więc tymi sondażami. Długo szukałem archiwalnych danych sondażowych, aż … Czytaj dalej Sondaże przedwyborcze http://blog.prokulski.science/index.php/2017/11/17/sondaze-przedwyborcze/
Urodziny w Wikipedii 2017-11-09 15:21:41 Przedstawiciele jakiego zawodu są najczęściej opisywani w Wikipedii? Czy miesiąc urodzenia predysponuje do wykonywania danego zawodu? Czy w polskiej Wiki więcej jest o Polakach czy innych nacjach? Pomysł Któregoś dnia, siedzimy w knajpie z J.P. a właściwie z J.A., z okazji jego urodzin. I tak od słowa do słowa pada “a dzisiaj urodziny ma też … Czytaj dalej Urodziny w Wikipedii http://blog.prokulski.science/index.php/2017/11/09/urodzenia-wg-wikipedii/
Jaki film obejrzeć? 2017-10-27 10:54:39 Kiedyś już pisałem o filmach i danych jakie dawno temu zgromadziłem z Filmwebu. Dzisiaj zajmiemy się polecaniem filmów do obejrzenia. Czyli – systemy rekomendacji. Dlaczego rekomendacje są ważne W najprostszym ujęciu chodzi o sprzedaż. Albo dosłowną sprzedaż towarów, albo odsłony (czy też odtworzenia) w serwisach internetowych (i tym samym odsłony reklam). Im więcej ludziom polecisz, … Czytaj dalej Jaki film obejrzeć? http://blog.prokulski.science/index.php/2017/10/27/na-co-do-kina/
Ankieta – wyniki (i jak je podsumować w R) 2017-10-17 16:38:17 Wyniki ankiety to jedno, a drugie to narzędzie do ich uzyskania i przedstawienia. Łączymy przyjemne z pożytecznym. Ankietę przygotowałem korzystając z Google Forms – to jedna z najwygodniejszych opcji (systemów do ankiet jest wiele), szczególnie jeśli chcemy mieć od razu dane (odpowiedzi) w postaci tabeli (w tym przypadku arkusza Google Sheets). Kiedy ankieta jeszcze trwała … Czytaj dalej Ankieta – wyniki (i jak je podsumować w R) http://blog.prokulski.science/index.php/2017/10/17/ankieta-wyniki/
Kalendarz z Policją 2017-10-14 09:54:47 W jednym z ostatnich odcinków “Ucha prezesa” było coś o tym, że teraz rząd ma mówić o tym, że jest bezpiecznie (zamiast “Przez osiem lat Polki i Polacy…”). Sprawdzimy zatem bezpieczeństwo na polskich drogach. Ale punktem wyjścia będzie specyficzny sposób pokazania danych dziennych. Widok kalendarza Dane dzienne (takie, które mają jedną wartość dla każdego dnia … Czytaj dalej Kalendarz z Policją http://blog.prokulski.science/index.php/2017/10/14/kalendarz-z-policja/
Kto pracuje najbardziej efektywnie w Europie? 2017-10-09 13:41:04 Czy wydajność pracy w różnych krajach Europy jest jednakowa? Jak skorzystać z danych Eurostatu w R? Jestem fanem facebookowej strony z różnymi mapkami. Na stronie tej pokazał się ostatnio obrazek z informacją o średniej liczbie godzin jaką w pracy spędzają mieszkańcy poszczególnych krajów (linkował do tego postu). Ale szczerze powiedziawszy co to za informacja? To … Czytaj dalej Kto pracuje najbardziej efektywnie w Europie? http://blog.prokulski.science/index.php/2017/10/09/kto-pracuje-najbardziej-efektywnie-w-europie/
Ankieta! 2017-10-04 16:33:09 Czytasz tego bloga? Jesteś fanem Dane i Analizy na Facebooku? (dlaczego nie?!) Wypełnij koniecznie ankietę! Zajmie Ci to góra pięć minut. http://blog.prokulski.science/index.php/2017/10/04/ankieta/

Teraz czas na Veturilo.

NextBike wystawia odpowiedniego XMLa ze stanem stacji we wszystkich obsługiwanych miastach. Na Warszawę składają się “miasta” (city) o numerze 210 (stacje miejskie) oraz 372 (stacje sponsorskie).

Ponieważ w Warszawie sezon Veturilo się skończył i na stacjach nie ma rowerów weźmiemy inne miasto – takie z numerem 1 (bodaj Lipsk w Niemczech). Na chwilę obecną (2017-12-12 13:52:08) to działało.

Oczywiście można wczytywać całego XMLa, ale szkoda ruchu sieciowego, stąd parametr ?city=xx (z odpowiednim xx) który zawęża wyniki do wskazanego miasta. Jeśli interesują Cię inne miasta – zerknij do XMLa od NextBike i wyszukaj w nim odpowiedni numerek.

Podobnie jak poprzednio parsujemy XMLa i szukamy odpowiedniego poziomu, do którego trzeba sięgnąć:

Tym razem jednak wartości jakie nas interesują są w ramach parametrów tagu XML. Zatem zamiast użyć xmlValue() użyjemy xmlAttrs().

Wyciągniemy na początek atrybuty wszystkich node’ów typu place do listy:

a następnie listę przepuścimy (element po elemencie) przez funkcję, która wybierze z atrybutów to co nas interesuje:

Funkcja buduje mini-tabelkę, gdzie każdy wiersz zawiera wszystkie dane o stacji i numer roweru na tej stacji. Takich wierszy jest tyle ile rowerów stoi na stacji. Dzięki temu w przyszłości wystarczy w dużej tabeli (takiej z kilku dni) wyszukać numer roweru i dostaniemy jego drogę (konkretnie: numery stacji na jakich był przypięty).

Oczywiście aby mieć historię trzeba dane z XMLa pobierać co jakiś czas (na przykład co 5 minut). I uzupełniać je o timestamp.

Zobaczmy do otrzymujemy dla naszego XMLa:

bike_number bikes uid number long lat name
10588 3 28 4013 12.368813753128 51.340505159701 Gottschedstr./Bosestr.
10141 3 28 4013 12.368813753128 51.340505159701 Gottschedstr./Bosestr.
20150 3 28 4013 12.368813753128 51.340505159701 Gottschedstr./Bosestr.
NA 0 72 4003 12.381554245949 51.339077567821 Augustusplatz/Oper
07026 5 125 4006 12.373212575912 51.339637215946 Thomaskirchhof/Taxistand
07033 5 125 4006 12.373212575912 51.339637215946 Thomaskirchhof/Taxistand
05678 5 125 4006 12.373212575912 51.339637215946 Thomaskirchhof/Taxistand
10622 5 125 4006 12.373212575912 51.339637215946 Thomaskirchhof/Taxistand
07022 5 125 4006 12.373212575912 51.339637215946 Thomaskirchhof/Taxistand
10189 1 128 4011 12.372853159904 51.337076853681 Burgplatz/Stadthaus
10027 1 801 4014 12.373319864273 51.320789736538 K.-Liebknecht-Str./K.-Eisner-Str./Bäcker
NA 0 1615 4007 12.365182042122 51.343068681395 Jahnallee/Thomasiusstr./Denkmal
10719 5 1727 4005 12.373394966125 51.324537727221 Südplatz (LVB Mobilitätsstation 10)
05534 5 1727 4005 12.373394966125 51.324537727221 Südplatz (LVB Mobilitätsstation 10)
05515 5 1727 4005 12.373394966125 51.324537727221 Südplatz (LVB Mobilitätsstation 10)
05656 5 1727 4005 12.373394966125 51.324537727221 Südplatz (LVB Mobilitätsstation 10)
20515 5 1727 4005 12.373394966125 51.324537727221 Südplatz (LVB Mobilitätsstation 10)
10742 4 2031 4021 12.367199063301 51.332032789785 Grassistr./Beethovenstr.
05639 4 2031 4021 12.367199063301 51.332032789785 Grassistr./Beethovenstr.
05784 4 2031 4021 12.367199063301 51.332032789785 Grassistr./Beethovenstr.

Te dane można opatrzyć aktualną datą i godziną oraz zapisać na przykład do bazy danych. Ten prosty kod (pobranie XMLa z sieci, parsowanie XMLa i wyciągnięcie odpowiednich danych) możemy zapakować w skrypt uruchamiany cyklicznie i wstawić go do unixowego Crona lub jakiegoś Task Schedulera w Windows. Są nawet R-pakiety do tego.

Podsumowując – aby pobrać dane z XMLa trzeba:

  • pooglądać tego XMLa, najwygodniej w edytorze tekstowym
  • po przeanalizowaniu struktury (sprawdzamy drzewko node’ów oraz czy wartości są w tagach czy jako ich atrybuty) na sucho przechodzimy do R:
  • parsujemy XMLa (xmlParse)
  • dla każdego node’a (używając do tego celu xpathSApply) wykonujemy xmlValue lub xmlAttrs

Prawda, że proste? Tylko strasznie upierdliwe, bo każdy XML może być inny… a te z Sharepointa to zgroza (szczególnie nazwy pól).

A jak w R pobrać dane z listy Sharepoint? Trzeba pobrać XMLa, co jest najtrudniejszym elementem. Dam Wam hint, bo przez to przechodziłem przez to niedawno:

To gotowa funkcja, która w parametrach przyjmuje:

  • URL do witryny Sharepoint
  • ID listy
  • ID widoku
  • login i hasło (otwartym tekstem) dostępu do Sharepointa

W odpowiedzi dostajemy listę (w rozumieniu obiektu typu list) z zawartością.

Dodaj komentarz