Instrukcja korzystania z API do danych statystycznych Eurostatu

Eurostat oferuje dostęp do całego zasobu danych ze swoich baz danych przez usługi sieciowe (API) w trzech formatach (SDMX, Json i Unicode):

image001

SDMX (Statistical Data and Metadata Exchange) – to międzynarodowy standard wymiany dany statystycznych wraz z metadanymi (opisami, uwagami itp.). W podstawowej wersji SDMX-ML wykorzystuje format XML.

Oferuje duże możliwości, ale nie jest powszechnie znany poza statystyką i wymaga czasu na naukę. Polecany jedynie dla pasjonatów lub osób, które są lub chcą być związane zawodowo ze statystyką lub planują zajmować się analizą zbiorów danych statystycznych.

Na potrzeby hackathonu polecamy prostszy interfejs dostępu do danych zwracający dane w formacie JSON-stat:

image002

 

Instrukcja krok po kroku

A. Jak wybrać dane

  1. będziemy potrzebować kodu zbioru danych, który pobieramy ze strony z bazami Eurostatu

image003

 

2. kopiujemy wybrany kod i wklejamy do Query Buildera i klikamy Next:

image006

Ważne, aby korzystać z kodu zbioru danych (z najniższego poziomu drzewa), a nie kodu dziedziny

np. zadziała nam demo_gind,                     

image004

a nie zadziała samo demo:

image005

3. Wybieramy za jaki okres mają być pobrane dane (polecamy dynamiczne określenie okresu np. dla ostatnich dostępnych 3 lat, kwartałów lub miesięcy lub od np. 2010 roku – zapewni to automatyczną aktualizację danych dla tworzonej aplikacji).  

Opcje w Time selection oznaczają:

Default – wszystkie dostępne okresy odniesienia w bazie (UWAGA w zależności od wskaźnika danych może być dość dużo i na początku prawidłowa interpretacja odpowiedzi serwera może być trudna)

Fixed – umożliwia swobodny wybór okresów odniesienia, ale tylko spośród już dostępnych (brak możliwości automatycznej aktualizacji)

Since  – wszystkie dostępne dane od wskazanego okresu np. od 2010 roku. Gdy pojawią się nowe dane w bazie, to dostaniemy dłuższy szereg. Opcja zapewnia automatyczną aktualizację danych, ale trzeba przewidzieć i zapewnić prawidłowe wyświetlanie coraz dłuższego szeregu danych w tworzonej aplikacji.

For Last – określona liczba kolejnych okresów odniesienia od najnowszych dostępnych. Opcja zapewnia automatyczną aktualizację danych i otrzymujemy zawsze szereg danych o stałej długości.

image007

Uwaga Może się zdarzyć, że 3 ostatnie dostępne lata obejmą rok, dla którego utworzono już odpowiednią kolumnę w bazie danych, ale jeszcze nie wprowadzono danych. Wtedy w pliku wynikowym zamiast wartości dla danego roku dostaniemy dwukropki " : " oznaczające brak danych. Jest to sytuacja przejściowa – dane wkrótce zostaną uzupełnione, ale tworząc aplikację trzeba uwzględnić taką możliwość.

4. Wybieramy kraje i inne obniesienia geograficzne (grupy krajów np. państwa należące do Unii Europejskiej lub regiony)

Opcje w Geo selection oznaczają:

Default – wszystkie dostępne w bazie (UWAGA w zależności od wskaźnika danych może być dość dużo i na początku prawidłowa interpretacja odpowiedzi serwera może być trudna)

Fixed – umożliwia swobodny wybór krajów lub regionów – polecamy na początek wybrać tylko kilka krajów

image008

5. Wybieramy wskaźniki, czyli rodzaje informacji statystycznej dostępnej w danym zbiorze danych np. liczbę ludności wg stanu z dania 1 stycznia danego roku:

image009

6. Decydujemy, czy chcemy mieć w naszym pliku wynikowym:

  1. Pogrupowane wskaźniki
  2. Wyłączyć nazwę zbioru danych w opisie wskaźnika
  3. Dane dla Unii Europejskiej i strefy Euro

Domyślnie wszystkie te opcje ustawione są na „nie” i zwykle może tak zostać.

7. Wybieramy z jaką dokładnością do miejsca po przecinku mają być podane dane – domyślnie jest jedno miejsce po przecinku i zwykle to wystarczy. UWAGA Jeśli dane składają się wyłącznie z liczb całkowitych (jak w naszym przypadku z liczbą ludności) niezależnie od tego jaką precyzję wybierzemy i tak dostaniemy wynik w postaci liczb całkowitych.

8. Klikamy przycisk Generate query filter i otrzymujemy zestaw parametrów do wklejenia do naszego zapytania do serwera Eurostatu.

UWAGA – jeśli widzimy pustą, białą stronę, to trzeba ją przewinąć do góry – powinniśmy zobaczyć takie okno z parametrami do naszego zapytania:

image010

Kopiujemy tekst z okna:   demo_gind?geo=EU28&geo=PL&precision=1&lastTimePeriod=3&indic_de=JAN

Nasz filtr składa się z kodu zbioru danych i kolejnych parametrów dołączanych po znaku ? i łączonych znakiem &.

B. Jak wygenerować link z zapytaniem do serwera i pobrać plik z danymi

1. Początek linku jest zawsze taki sam: http://ec.europa.eu/eurostat/wdds/rest/data/v2.1/json/en/

2. Doklejamy do niego filtr wygenerowany w poprzednim kroku: http://ec.europa.eu/eurostat/wdds/rest/data/v2.1/json/en/demo_gind?geo=EU28&geo=PL&precision=1&lastTimePeriod=3&indic_de=JAN

3. Testujemy działanie naszego linku – klikamy i przechodzimy do podanej strony (przeglądarka Firefox pokoloruje nam składnię i pokaże nam dane w bardziej czytelny sposób):

image011

Link działa poprawnie, serwer Eurostatu zwraca żądane dane w formacie Json. Można wykorzystać usługę sieciową działającą pod podanym adresem do pobierania danych do tworzonej aplikacji. Aby jednak sensownie ich użyć programista musi umieć je poprawnie zinterpretować i o tym będzie następna część instrukcji.

C. Jak interpretować odpowiedź serwera

1. version : "2.0"

to wersja usługi sieciowej Eurostatu (niestety, jak się zmieni wersja (np. na 3.0), to może pojawić się problem z pobieraniem danych. Przy zmianie np. z 2.0 na 2.1 nie powinno być problemów.)

2. label :   "Population change - Demographic balance and crude rates at national level"

to nazwa zbioru danych z których korzystamy (o nazwie kodowej demo_gind) – UWAGA zbiór danych zwykle zawiera wiele wskaźników, a w tym przykładzie wybraliśmy tylko jeden, więc to nie jest dobra nazwa dla naszego zestawu danych zapisanego w pliku Json. W naszym przypadku to nazwa obiektu nadrzędnego.

3. href : "http://ec.europa.eu/eurostat/wdds/rest/data/v2.1/json/en/demo_gind?geo=EU28&geo=PL&precision=1&lastTimePeriod=3&indic_de=JAN"

oczywiste - to link do zbioru danych, podobnie nie wymagają komentarza kolejne dwie linie:

4. source : "Eurostat"

5. updated : "2017-11-08"

6. status   :

0 : "bep"

1 : "bep"

2 : "bep"

To są kody (skróty) uwag metodologicznych (notek). Opisy notek są podane dalej, w sekcji extension :

status :

label :   

b : "break in time series"

e : "estimated"

p : "provisional"

Wiemy więc, że dla pierwszych trzech wartości (czyli jak się dalej przekonamy dla danych dla UE) są przerwy w szeregu czasowym (dla tych wskaźników demograficznych bardzo długim, bo sięgającym lat 60. XX wieku) i że są to dane szacunkowe oraz wstępne.

Ponieważ w naszym zestawie mamy dane tylko dla lat 2015-2017, gdzie nie ma przerw w szeregu czasowym, więc ta pierwsza informacja jest nieistotna. Dobrze jednak wiedzieć, że są to dane szacunkowe i wstępne, czyli, że mogą się zmienić.

Dobrą praktyką jest poinformowanie użytkowników tworzonej aplikacji o wszelkich notkach dotyczących pokazywanych im danych, ale można to zrobić na dwa sposoby:

  1. albo wyświetlać własne opisy na podstawie notek Eurostatu – wtedy jednak programista sam musi decydować, które notki są istotne (bo gdy pokazuje krótki, ale pełny szereg czasowy i „automatycznie” zamieści notkę, że w szeregu czasowym są przerwy, to tylko wprowadzi użytkowników w błąd)
  2. albo pod wykresem, mapką lub inną wizualizacją danych umieścić link źródło danych prowadzący do tabeli z danymi (tej z której pobraliśmy kod zbioru danych w kroku pierwszym). Wtedy odpowiedzialność za opisanie metodologii uzyskania pokazywanych danych przejmuje dostawca, czyli Eurostat. Na potrzeby hackathonu polecamy to drugie rozwiązanie.

7. extension :       

datasetId : "demo_gind"

lang : "EN"

description : null

subtitle : null

status :

label :  

b : "break in time series"

e : "estimated"

p : "provisional"

Ta część zawiera dodatkowe opis i informacje dotyczące naszych danych. Opisy statusu zostały omówione powyżej, a pozostałe elementy (kod zbioru danych, język) nie wymagają komentarza.

8. class : "dataset"    

Informacja, że otrzymaliśmy obiekt klasy „Zbiór danych”.

9. value : 

0 : 508504320

1 : 510278701

2 : 511805088

3 : 38005614

4 : 37967209

5 : 37972964

To zawartość poszczególnych komórek, ale jeszcze nie wiemy jaką strukturę danych należy do nich zastosować.  O tym będzie w następnym punkcie.

10. dimension :       

indic_de :          

label : "indic_de"

category :          

index :

JAN : 0

label :  

JAN : "Population on 1 January - total "

geo :    

label : "geo"

category :          

index :

EU28 : 0

PL : 1

label :

EU28 : "European Union (28 countries)"

PL : "Poland"

time :   

label : "time"

category :          

index :

2015 : 0

2016 : 1

2017 : 2

label :

2015 : "2015"

2016 : "2016"

2017 : "2017"

Mamy trzy wymiary: wskaźnik, obszar geograficzny i czas.

Ogólnie strukturą danych zbioru danych z bazy Eurostatu jest więc kostka wielowymiarowa (oprócz powyższych trzech wymiarów, mających zastosowanie do wszystkich wskaźników, mogą być jeszcze dalsze podziały np. na płeć).

Przygotowując sobie kontener na dane można użyć tablicy wielowymiarowej o rozmiarze podanym w punkcie 11 (size :), lub bardziej uniwersalnej wielowymiarowej ArrayListy.

W naszym przykładzie mamy tylko jeden wskaźnik, więc struktura danych to tabela dwuwymiarowa:

geo \ time

0

1

2

0

     

1

     

Uzupełniając ją o kody i opisy już w języku polskim otrzymamy:

    

time

0

1

2

kod

2015

2016

2017

geo

kod

opis

2015

2016

2017

0

EU28

Unia Europejska

     

1

PL

Polska

     

Wartości z punktu 8 wstawiamy kolejno w komórki (wg numerów / indeksów):

    

time

0

1

2

kod

2015

2016

2017

geo

kod

opis

2015

2016

2017

0

EU28

Unia Europejska

0

1

2

1

PL

Polska

3

4

5

Podstawiając w miejsce numerów wartości otrzymamy:

    

time

0

1

2

kod

2015

2016

2017

geo

kod

opis

2015

2016

2017

0

EU28

Unia Europejska

508504320

510278701

511805088

1

PL

Polska

38005614

37967209

37972964

Nazwą naszej tabeli jest nazwa wskaźnika:

label :  

JAN : "Population on 1 January - total "

Po polsku: Liczba ludności ogółem wg stanu z 1 stycznia danego roku.

Tabela sformatowana w sposób czytelny dla ludzi powinna więc wyglądać tak:

Liczba ludności ogółem wg stanu z 1 stycznia danego roku

 

2015

2016

2017

Unia Europejska

508 504 320

510 278 701

511 805 088

Polska

38 005 614

37 967 209

37 972 964

źródło danych

Jeżeli dla ostatniego roku otrzymaliśmy same dwukropki " : " zamiast wartości, to znaczy, że Eurostat dodał już kolumnę z najnowszym rokiem do bazy danych, ale nie wypełnił jej jeszcze wartościami. Dane wkrótce się pojawią, ale trzeba przygotować aplikacje na możliwy drak danych oraz poinformować użytkowników co się stało i dlaczego zamiast spodziewanych np. 3 lat na wykresie lub innej wizualizacji widzą tylko dwa lata.  

11. id :        

0 : "indic_de"

1 : "geo"

2 : "time"                          

To kody poszczególnych wymiarów.

12. size :    

0 : 1

1 : 2

2 : 3

To rozmiary naszej kostki wielowymiarowej.

Możemy łatwo obliczyć ile danych otrzymamy: 1 x 2 x 3 = 6 wartości.

Jeśli wyślemy nie sparametryzowane zapytanie do serwera Eurostatu o dane z tego samego kodu:

http://ec.europa.eu/eurostat/wdds/rest/data/v2.1/json/en/demo_gind

 to otrzymamy:

image012

Rozmiary wynikowej kostki to 27 wskaźników x 58 krajów x 58 lat = 90828 wartości. Nie jest to naprawdę duży zbiór danych, ale osobom bez przygotowania praca z nim może sprawić trudność. Oczywiście taka ilość danych jest też zupełnie niepraktyczna do pokazywania użytkownikom – trzeba je już sprytnie filtrować przed wizualizacją.

Unicode

Jeśli zamiast danych w formacie Json preferujesz dane w formacie Unicode, to wystarczy zamienić w naszym przykładowym linku słowo json na unicode:

http://ec.europa.eu/eurostat/wdds/rest/data/v2.1/unicode/en/demo_gind?geo=EU28&geo=PL&precision=1&lastTimePeriod=3&indic_de=JAN

Odpowiedź serwera jest czytelniejsza dla człowieka, niż w przypadku nieprzetworzonych danych Json:

META	CODE	Name	Population change - Demographic balance and crude rates at national level, Population on 1 January - total 	Population change - Demographic balance and crude rates at national level, Population on 1 January - total 	Population change - Demographic balance and crude rates at national level, Population on 1 January - total 
ID			demo_gindJAN	demo_gindJAN	demo_gindJAN
DESCRIPTION			Code: demo_gind<br/>Data last updated on: 08.11.2017	Code: demo_gind<br/>Data last updated on: 08.11.2017	Code: demo_gind<br/>Data last updated on: 08.11.2017
UNIT						
FLAGS				b=break in time series;e=estimated;p=provisional	b=break in time series;e=estimated;p=provisional	b=break in time series;e=estimated;p=provisional
PARSETYPE	S	S	F	F	F
PRECISION			1	1	1
SLICE	NA	NA	2015	2016	2017
	EU28	European Union (28 countries)	508504320(b,e,p)	510278701(b,e,p)	511805088(b,e,p)
	PL	Poland	38005614	37967209	37972964

Metadane, kod i nazwa zbioru danych jest taka sama i składa się z nazwy zbioru danych Eurostatu i nazwy wskaźnika.

Identyfikator (połączone kody zbioru danych i wskaźnika), opis (kod zbioru danych i data modyfikacji) oraz flagi (notki) z jakiegoś powodu są powtórzone trzy razy (dla każdego wiersza w tabeli osobno).

Nie podano jednostek – pole Unit jest puste. Wiemy jednak, że wartości w tabeli dotyczą liczby ludności, więc jednostkami miary w tym przypadku są osoby. Być może gdyby podawano dane w tysiącach lub milionach osób w tym miejscu pojawiłaby się odpowiednia informacja.

Podany typ danych (PARSETYPE) w kolejnych kolumnach tabeli – S to String, F – Float. Niestety nie uwzględniono kodów notek dołączonych do wartości liczbowych np. 508504320(b,e,p),więc konwertowanie takiego ciągu znaków na liczbę zmiennoprzecinkową zakończy się błędem. Trzeba najpierw oddzielić notki.

Liczba miejsc po przecinku jest taka jaką podaliśmy z zapytaniu. UWAGA Nie dotyczy to rodzaju liczby zmiennoprzecinkowej (float single precision). Jeśli dane składają się wyłącznie z liczb całkowitych (jak w naszym przypadku z liczbą ludności) niezależnie od tego jaką precyzję wybierzemy i tak dostaniemy wynik w postaci liczb całkowitych.

Tabela z danymi (wybrany przekrój z kostki trójwymiarowej) składa się z trzech wierszy, z których pierwszy zawiera nazwy kolumn, z wyjątkiem dwóch pierwszych pozycji oznaczonych NA (not applicable).