
Wprowadzenie
Dzięki jednej z poprzednich lekcji wiemy już, że interfejs programistyczny czy maszynowy (Application Programming Interface, API) to alternatywna wobec klasycznego przeglądania witryny metoda korzystania ze zbiorów cyfrowych dziedzictwa. Zamiast strona po stronie oglądać obiekty i pobierać ich metadane i wizerunki, możemy użyć API i szybko pobrać interesujące nas informacje.
Omówiona w tamtej lekcji metoda ręcznego wysyłania zapytań do API przez jakieś zewnętrzne narzędzie nie jest w żaden sposób optymalna - praktyka pracy z interfejsem programistycznym jest zupełnie inna. W niniejszej lekcji nauczymy się pracować z API za pomocą języka R. Język R - podobnie jak Python - jest powszechnie używany do pracy z danymi.
Źródłem danych w tej lekcji będą zbiory londyńskiej Wellcome Collection. Interesować nas będą drzeworyty szwajcarskiego rytownika i malarza Josta Ammana (1539-1591). Oczywiście w ramach ćwiczenia możecie wybrać innego dowolnego autora z Wellcome Collection. Daty życia Ammana wskazują, że pracować będziemy ze zbiorami z domeny publicznej - warto wziąć to pod uwagę.
Cele lekcji
Celem lekcji jest wdrożenie do pracy z API instytucji dziedzictwa z wykorzystaniem metod języka R oraz zdobycie umiejętności korzystania z platformy Posit.cloud, pozwalającej na pracę w tym języku bezpośrednio w przeglądarce, bez konieczności instalowania czegokolwiek na własnym komputerze.
Efekty
- znajomość podstawowych możliwości platformy Posit.cloud,
- podstawy składni i metod języka R,
- praca z API instytucji dziedzictwa w języku R i eksportu danych do plików CSV.
Wymagania
Do korzystania z lekcji konieczne są:
- przeglądarka internetowa,
- założenie darmowego konta na platformie Posit.cloud.
Posit.cloud to produkt firmy odpowiedzialnej za RStudio - powszechnie wykorzystywany edytor i środowisko programistyczne dla języka R.
Część merytoryczna
Podzielmy naszą pracę na trzy etapy. W pierwszym zapoznamy się ze środowiskiem Posit.cloud, w drugim - z podstawami pracy z językiem R. trzeci etap pracy to pozyskiwanie danych z Wellcome Collection i proste ich opracowanie.
Posit.cloud - IDE dla języka R
Zintegrowane środowisko programistyczne (Integrated Development Environment, IDE) to zestaw narzędzi służących do pisania, testowania, sprawdzania błędów i wdrażania oprogramowania. W IDE znajdziemy takie elementy jak edytor kodu i konsolę, interpreter języka, pozwalający na korzystanie z niego czy narzędzia do zarządzania projektem i kontroli wersji. IDE udostępnia to wszystko w spójnym graficznym interfejsie użytkownika.
IDE udostępniane w ramach Posit.cloud jest identyczne z IDE desktopowego programu RStudio.
W Posit.cloud, tak jak w RStudio, możemy pisać własne skrypty w języku R, analizować dane i je wizualizować, instalować pakiety rozszerzające możliwości R.
To dobry moment, żeby zarejestrować konto i zalogować się na Posit.cloud. Po zalogowaniu po lewej stronie ekranu pojawi się menu Spaces. Wybieramy YourWorkspace - to pusta jeszcze przestrzeń na nasze eksperymenty.
Po wejściu w naszą przestrzeń roboczą możemy założyć pierwszy projekt. Wybieramy New RStudio Project.
Po założeniu projektu możemy nadać mu nazwę (na górze strony). W nagłówku strony, nieco po prawej, znajduje się ikona przypominająca wskaźnik jakiegoś urządzenia pomiarowego. Jeśli klikniemy w nią, zobaczymy, w czym tak naprawdę pracujemy. Chociaż cały czas korzystamy z przeglądarki, to pracujemy na prawdziwym systemie operacyjnym (w tym przypadku Ubuntu) i mamy przydzielone określone zasoby komputera (m.in. pamięć RAM). Warto o tym pamiętać planując bardziej zaawansowane prace w Posit.cloud - zasoby otrzymywane w ramach darmowego konta mogą do tego nie wystarczyć i konieczne może być wykupienie płatnej subskrypcji.
Posit.cloud - podstawowe elementy
Nasza przestrzeń robocza składa się z kilku głównych komponentów. Mamy dostęp do edytora kodu z funkcjami ułatwiającymi programowanie, takimi jak podświetlanie składni, automatyczne uzupełnianie czy automatyczne wcięcia. Przy starcie systemu edytor jest niewidoczny. Aby go zobaczyć, wybierzmy dolne okno z prawej strony, prezentujące listę plików. Stwórzmy tam plik (New Blank File - R Script) i nazwijmy go wellcome.R. Edytor programistyczny pojawi się w lewej górnej części IDE.
Poniżej edytora znajduje się konsola, do której bezpośrednio możemy wpisywać polecenia w języku R oraz widzieć efekty ich działania. Po prawej stronie IDE, w oknie z listą plików, dostępne są też inne zakładki. Najważniejsza z nich to pakiety (Packages) - lista rozszerzeń języka R, z której będziemy korzystać. Nad tym oknem znajduje się okno środowiska - wylistowane są tam wszystkie funkcje i obiekty (z danymi), które będziemy tworzyć w czasie naszej pracy z API.
Dobrą stroną chmurowego środowiska programistycznego jest to, że można w nim eksperymentować bez obaw - jeśli coś pójdzie nie tak, zawsze możemy skasować bieżący projekt i uruchomić nowy bez robienia bałaganu na własnym komputerze.
Podstawy składni R
Każdy język naturalny ma określone zasady, które pozwalają nam się komunikować. Wiemy na przykład, że w polskim literackim języku pisanym standardowo zaczynamy zdanie od wielkiej litery i kończymy kropką. Nawet takie drobne elementy języka jak przecinki są w stanie radykalnie zmienić przekaz zdania (nie idź do pracy ma zupełnie inne znaczenie niż nie, idź do pracy). Znaczenie ma też kolejność wyrazów i ich odmiana. Języki programowania także wymagają respektowania określonych zasad.
Spróbujmy w końcu napisać coś w języku R. Niech naszym zadaniem będzie policzenie znaków w zdaniu “Muzea cyfrowe zwiększają dostęp do zbiorów dziedzictwa”. W naszym pliku wellcome.R wpiszmy:
z <- 'Muzea cyfrowe zwiększają dostęp do zbiorów dziedzictwa'
Zwróćmy uwagę na strzałkę skierowaną w lewo. To tzw. operator przypisania. Efektem naszego programu (jeśli za chwilę wyślemy tę linijkę do konsoli) będzie przypisanie do obiektu z treści tekstowej (stringu). Aby wysłać linijkę do konsoli, zaznaczamy całą linijkę myszą i klikamy ENTER (możemy też z edytora wybrać opcję Run). Jeśli to się nam uda, w górnym oknie po prawej stronie (oknie środowiska) zobaczymy nowoutworzony obiekt i jego treść.
Jeśli w konsoli wpiszemy teraz z, wyświetli się nam tekstowa treść obiektu z:
> z
[1] "Muzea cyfrowe zwiększają dostęp do zbiorów dziedzictwa"
Znaczek [1] jest tutaj informacją o tym, że w obiekcie z znajduje się tylko jeden element.
W języku R mamy dostęp do rozmaitych rodzajów obiektów i ciągi tekstowe (wektory tekstowe) to tylko jedne z nich. W naszej pracy z API korzystać będziemy jeszcze z ramek danych (data frame), bardzo przypominające klasyczne tabele (takie jak te znane z Excela), złożone z kolumn i wierszy.
Język R to także funkcje, które nie tylko pozwalają nam pracować z danymi, ale też komunikować się z API. Prostą funkcją, która w końcu pozwoli nam wyliczyć liczbę znaków zdania z wektora z jest nchar(). Wpiszmy w konsolę:
nchar(z)
a uzyskamy:
> nchar(z)
[1] 54
Wektor z jest obiektem zawierającym ciąg tekstowy. Wysyłamy go do funkcji nchar() jako parametr. W zdaniu Muzea cyfrowe zwiększają dostęp do zbiorów dziedzictwa są 54 znaki. Wyniki funkcji mogą być zapisywane do nowych obiektów.
> l <- nchar(z)
> l + 10
[1] 64
W tym prostym eksperymencie liczyliśmy liczbę znaków w naszym zdaniu funkcją nchar() i przypisaliśmy do wektora liczbowego l. Skoro to wektor liczbowy, to możemy robić na nim operacje matematyczne.
Więcej na temat języka R nauczyć się można z podręcznika Jakuba Nowosada, który bardzo polecam. W tej lekcji korzystać będziemy tylko z niektórych jego możliwości i z ograniczonej składni.
Potrzebujemy pakietu do komunikacji z API
Nie próbuj odkrywać koła na nowo - to dobra porada dla wszystkich, którzy zajmują się programowaniem. Po co budować od podstaw narzędzie do komunikacji z API, skoro mamy je już dostępne w pakiecie rozszerzającym możliwości języka R o nazwie jsonlite. Warto zauważyć, że pakiety R publikowane są niekiedy z tekstami naukowymi, które opisują ich budowę i zasady działania - tak jest też w przypadku jsonlite. Korzystając z tego pakietu w pracy naukowej warto zacytować tę publikację.
jsonlite to pakiet do pracy z danymi w postaci JSON, którą znamy już z poprzednich lekcji. Aby zainstalować go w środowisku, wybieramy dolne okno po prawej stronie (zakładka packages) i klikamy na install. Wpisujemy jsonlite i po chwili możemy zainstalować pakiet. Jeśli się to nam uda, nazwa pakietu znajdzie się na liście wszystkich pakietów w środowisku. Kliknięcie na nią wyświetli plik pomocy z omówieniem metod i składni, które pozwolą na pracę z jsonlite. Aby aktywować pakiet, zaznaczamy go na liście - w tym momencie w konsoli powinno pojawić się:
library(jsonlite)
Wydaje się, że jesteśmy gotowi do sięgnięcia po dane z Wellcome Collection.
Dokumentacja API to podstawa
Wellcome Collection to powstałe w 2007 roku londyńskie muzeum i biblioteka, gromadząca m.in. zbiory dotyczące szeroko pojętej medycyny. Znajdują się w nim także artefakty i dzieła sztuki związane z innymi tematami, m.in. XVI-wieczne drzeworyty Josta Ammana.
Drzeworyty szwajcarskiego artysty przeglądać możemy w przejrzystej i wygodnej witrynie Wellcome Collection, jednak nam bardzo zależy na uchwyceniu ich za pomocą API. Korzystanie z API może być konieczne przy pracy badawczej ze zbiorami cyfrowymi lub do ich masowego pozyskania w celu dalszego przetwarzania i wykorzystania - w końcu duża część z nich to zbiory z domeny publicznej.
Wellcome Collection udostępnia specjalną stronę dla deweloperów i deweloperek, na której znajdziemy dokumentację API. To kluczowa wiedza, bez której nie uda nam się nie tylko pobrać żadnych danych, ale nawet wysłać poprawnego żądania do serwerów tej instytucji. Warto pamiętać, że wciąż jesteśmy gośćmi i musimy stosować się do zaleceń instytucji dbającej o odpowiedzialne i poprawne udostępnianie swoich zbiorów.
Ponieważ dopiero zaczynamy pracę z API, skorzystajmy z API danych katalogowych, które udostępnia proste metody pozyskiwania danych. Kluczowe jest znalezienie adresu endpoint - adresu URL, do którego będziemy wysyłać żądania. Adres ten musi być uzupełniony o elementy kwerendy, zgodnie z dokumentacją API.
Lektura dokumentacji pozwala na przygotowanie takiego zestawienia adresu żądania:
ELEMENT URL | WARTOŚĆ |
---|---|
endpoint | https://api.wellcomecollection.org/catalogue/v2/works |
kwerenda | ?query= |
fraza wyszukiwania | Amman Jost |
Finalnie, adres żądania przyjmie postać:
https://api.wellcomecollection.org/catalogue/v2/works?query=Amman Jost
Możemy sprawdzić poprawność tego żądania, wklejając adres do pola adresowego przeglądarki. W efekcie powinniśmy zobaczyć dane w postaci JSON:
A tutaj możemy je dokładnie obejrzeć:
{
"type":"ResultList",
"pageSize":10,
"totalPages":12,
"totalResults":113,
"results":[
{
"physicalDescription":"facsimiles, illustrations.",
"workType":{
"id":"a",
"label":"Books",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/thumbs/b24852429_0007.jp2/full/!200,200/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"y52ug5tb",
"title":"Jost Amman's Stände und Handwerker mit Versen von Han Sachs / [Jost Amman].",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
]
},
{
"physicalDescription":"120 pages : illustrations ; 20 cm.",
"workType":{
"id":"a",
"label":"Books",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/thumbs/b24867676_0007.jp2/full/!200,200/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"yfjrzbja",
"title":"Frauen-Trachtenbuch / [Jost Amman].",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
]
},
{
"physicalDescription":"1 print : woodcut ; sheet 8 x 6 cm",
"description":"<p>In the German publication, described as \"Pfeiffen und Zincken\". Three musicians playing \"a straight cornetto (Zink) on the left, a flute in the centre, and a cross flute on the right\" (British Museum online catalogue)</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/V0040348EL/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"kexdtv6t",
"title":"Three men playing wind instruments. Woodcut by Jost Amman, 1568.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
],
"referenceNumber":"33973i"
},
{
"physicalDescription":"1 print : woodcut ; image 7.8 x 6 cm",
"description":"<p>In the German publication, described as \"Der Balbierer\"</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/L0019297/full/300,/0/default.jpg",
"license":{
"id":"cc-by",
"label":"Attribution 4.0 International (CC BY 4.0)",
"url":"http://creativecommons.org/licenses/by/4.0/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"py5v248x",
"lettering":"IA",
"title":"A barber cutting a man's hair. Woodcut by Jost Amman.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
}
],
"referenceNumber":"29872i"
},
{
"physicalDescription":"1 print : woodcut ; 10.5 x 14 cm.",
"description":"<p>Bible. N.T. Matthew 8.2-3; Mark 1.40-42; Luke 5.12-13. The man with leprosy has a cloth over his mouth and a clapper (to make a noise to warn of his arrival) around his belt, along with a bowl. In the distance Christ approaches the city gates, where a group of people await him; one kneels before him</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/L0016741/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"mdrqa3nx",
"title":"Christ healing a man of leprosy. Woodcut, 1571, after Jost Amman.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
}
],
"referenceNumber":"6i"
},
{
"physicalDescription":"1 print : woodcut ; sheet 8.2 x 6.4 cm",
"description":"<p>In the German publication, described as \"Harpff und Laut\". Three musicians playing (left to right) a lute, a horn and a harp. The harpist rests his foot on another lute on the ground</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/V0040348ER/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"em3249ev",
"title":"Three men playing wind and string instruments. Woodcut by Jost Amman, 1568.",
"type":"Work",
"availabilities":[
{
"id":"online",
"label":"Online",
"type":"Availability"
}
],
"referenceNumber":"33975i"
},
{
"physicalDescription":"1 print : woodcut ; sheet 8 x 6 cm",
"description":"<p>In the German publication, described as \"Der Seyler\"</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/V0040547EBC/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"fvz33hzq",
"title":"A ropemaker and his assistant making ropes for use in ships, building, and hunting. Woodcut by Jost Amman.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
],
"referenceNumber":"34960i"
},
{
"physicalDescription":"1 print : woodcut",
"description":"<p>In the German publication, described as \"Der Doctor ... ein Doctor von Artzney\"</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/V0025528/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"rsvhcpva",
"title":"A physician holding up a flask of urine for an old lady holding a basket and walking stick. Woodcut by Jost Amman.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
],
"referenceNumber":"35399i"
},
{
"physicalDescription":"1 print : woodcut ; sheet 8.4 x 6.5 cm",
"description":"<p>In the German publication, described as \"Der Lautenmacher.\"</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/V0040349EBL/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"evwp5srg",
"lettering":"I.A.",
"title":"A lute-maker testing one of the lutes in his workshop: other musical instruments are hanging on the walls, and there are tools on and around the workbench. Woodcut by Jost Amman, 1568.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
],
"referenceNumber":"33978i"
},
{
"physicalDescription":"1 print : woodcut ; sheet 8.3 x 6.3 cm",
"description":"<p>In the German publication, described as \"Der Lautenmacher.\"</p>",
"workType":{
"id":"k",
"label":"Pictures",
"type":"Format"
},
"thumbnail":{
"url":"https://iiif.wellcomecollection.org/image/V0040349EBR/full/300,/0/default.jpg",
"license":{
"id":"pdm",
"label":"Public Domain Mark",
"url":"https://creativecommons.org/share-your-work/public-domain/pdm/",
"type":"License"
},
"accessConditions":[
],
"locationType":{
"id":"thumbnail-image",
"label":"Thumbnail image",
"type":"LocationType"
},
"type":"DigitalLocation"
},
"alternativeTitles":[
],
"id":"n7cdtqub",
"lettering":"I.A.",
"title":"A lute-maker testing one of the lutes in his workshop: other musical instruments are hanging on the walls, and there are tools on and around the workbench. Woodcut by Jost Amman, 1568.",
"type":"Work",
"availabilities":[
{
"id":"closed-stores",
"label":"Closed stores",
"type":"Availability"
},
{
"id":"online",
"label":"Online",
"type":"Availability"
}
],
"referenceNumber":"33982i"
}
],
"nextPage":"https://api.wellcomecollection.org/catalogue/v2/works?query=Amman+Jost&page=2"
}
Serwer API poinformował nas, że w kolekcji Wellcome dostępnych jest 113 obiektów, których autorem jest Jost. Nie wiemy, czy wszystkie z nich to drzeworyty - to sprawdzimy później. W odpowiedzi otrzymaliśmy też listę 10 pierwszych obiektów oraz w polu nextPage adres kolejnej strony wyników wyszukiwania.
Wysyłanie żądania do API przez R
Zacznijmy od stworzenia obiektu api_url, w którym zapiszemy adres URL żądania:
api_url <- 'https://api.wellcomecollection.org/catalogue/v2/works?query=Amman Jost'
Zaznaczamy linię i klikamy enter - api_url jest już w środowisku. Jak widać, na razie pracujemy wyłącznie z pierwszą stroną wyników wyszukiwania. Skorzystajmy teraz z pakietu jsonlite. Jest w nim dostępna funkcja fromJSON():
fromJSON(
txt,
simplifyVector = TRUE,
simplifyDataFrame = simplifyVector,
simplifyMatrix = simplifyVector,
flatten = FALSE,
...
)
Funkcja fromJSON przyjmuje wiele parametrów, dla nas istotny będzie parametr txt - to (jak czytamy w dokumentacji pakietu) albo ciąg tekstowy (czyli jakieś dane w postaci JSON) albo adres URL, który zwraca dane w postaci JSON. W naszym przypadku tym adresem będzie adres żądania API. Wynik funkcji zapiszmy do obiektu response. Parametr flatten = TRUE pozwoli nam przetworzyć dane JSON tak, aby pasowały do dwuwymiarowej tabeli - spłaszczenie danych to bardzo ważny element naszej pracy.
response <- fromJSON(api_url, flatten = TRUE)
Udało się! W oknie pokazującym elementy środowiska widać już obiekt response. To złożona struktura, odpowiadająca dokładnie postaci pliku JSON, który został wygenerowany przez odpowiedź serwera.
Przetwarzanie odpowiedzi serwera
Poszczególne elementy obiektu response (będącego listą) możemy wyświetlać, korzystając ze znaku dolara ($). Robimy to w konsoli:
Jak widać, elementem odpowiedzi jest i ciąg tekstowy…
> response$type
[1] "ResultList"
jak i liczba
> response$totalResults
[1] 113
jak i na pozór skomplikowana struktura danych w response$results. To właśnie ramka danych. Spróbujmy włożyć ją do osobnego obiektu o nazwie items:
items <- response$results
W oknie wyświetlającym elementy środowiska znajdziemy ten obiekt oraz informację, że zawiera 10 wierszy (obserwacji) i 11 zmiennych (kolumn). Brzmi znajomo? Tak, to tabela! Kliknięcie na ikonę tabeli po prawej stronie wyświetli nam ramkę danych:
Wpisane do konsoli polecenie names(items) wyświetli nam listę wszystkich nazw kolumn:
> names(items)
[1] "physicalDescription" "alternativeTitles" "id" "title"
[5] "type" "availabilities" "description" "referenceNumber"
[9] "lettering" "workType.id" "workType.label" "workType.type"
[13] "thumbnail.url" "thumbnail.accessConditions" "thumbnail.type" "thumbnail.license.id"
[17] "thumbnail.license.label" "thumbnail.license.url" "thumbnail.license.type" "thumbnail.locationType.id"
[21] "thumbnail.locationType.label" "thumbnail.locationType.type"
a funkcją nrow() sprawdzimy liczbę wierszy:
> nrow(items)
[1] 10
Wszystko się zgadza - API zwraca do 10 obiektów na stronę wyników wyszukiwania. Jeśli z uwagą obejrzymy pozyskaną ramkę danych zauważymy, że w niektórych kolumnach znajdują się bardziej złożone dane niż ciągi tekstowe czy liczby. JSON to format doskonale radzący sobie z danymi w złożonej strukturze, czego nie można powiedzieć o dwuwymiarowej tablicy wyświetlanej na ekranie. Na szczęście wszystkie pozyskane dane obecne są w obiekcie items.
Mając to na uwadze, spróbujmy wyeksportować fragment ramki danych do pliku CSV. Pliki CSV to taki sposób przechowywania danych, gdzie każdy rekord jest oddzielony przecinkiem, a nowa linia oznacza nowy rekord. Często używa się ich do przechowywania tabelkowych danych, na przykład arkuszy Excela. Dane z plików CSV także latwo importować do desktopowych arkuszy kalkulacyjnych czy Google Sheets.
Proste przetworzenie tabeli i eksport do CSV
Wybierzmy tylko kilka kolumn z tej ramki danych i wyeksportujmy je do CSV. W tym celu potrzebujemy pakietu dplyr i dostępnej w jego ramach funkcji select(). Instalujemy ten pakiet podobnie jak jsonlite i włączamy go do środowiska (zaznaczając pole przy nazwie pakietu na liście pakietów).
works <- items %>% select(id, workType.label, title, description, thumbnail.url)
Ta składnia może wydawać się dziwna, ale jest poprawna. Znak %>% (kombinacja CTRL + SHIFT + M) to operator udostępniany z pakietem dplyr. Ułatwia on pracę ze skomplikowanymi funkcjami. Jeśli uważnie przyjrzymy się tej linijce kodu, to zobaczymy, że do obiektu works przypisywany jest wynik funkcji select(), która jako parametry bierze nazwy kolumn. Funkcja ta wywoływana jest na obiekcie items (naszej ramce danych). Operator %>% (czytany jako then) działa jak potok, przekazując wartości ze swojej lewej strony (items) jako argument do funkcji po prawej stronie (select).
W naszej tabeli CSV znajdą się identyfikatory obiektów, ich typ, tytuł, opis oraz adres URL skanu. Pozostaje nam tylko wyeksportować nową ramkę danych (works) do pliku:
> write.csv(works, 'works.csv', row.names = FALSE)
Funkcja write.csv przyjmuje jako parametry obiekt z ramką danych (works), nazwę pliku (works.csv) oraz informację o numerowaniu wierszy (nie chcemy tego).
Aby pobrać te dane z Posit.cloud należy wyeksportować projekt - opcja dostępna jest na liście projektów w ramach naszego przestrzeni roboczej.
API Wellcome Collection informowało nas jednak, że wszystkich obiektów Josta Ammana jest 113. Pobraliśmy i przetworzyliśmy jedynie 10 - jak automatycznie pobrać wszystkie informacje? O tym dowiemy się w kolejnej części tej lekcji.
Podsumowanie
Posit.cloud to świetne rozwiązanie do nauki języka R, wykorzystywanego powszechnie do pracy z danymi i korzystania z różnorodnych API. W ramach tej lekcji poznaliśmy podstawowe elementy IDE umożliwiającego tworzenie obiektów i uruchamianie funkcji w języku R, a pakiety jsonlite i dplyr pozwoliły nam pobrać dane z API i w podstawowy sposób je przetworzyć.
Wykorzystanie metod
Język R jest wykorzystywany do analiz danych, przetwarzania tekstów, tworzenia wizualizacji i pracy z mapami cyfrowymi. W R korzystać można też z rozwiązań sztucznej inteligencji. Wykorzystanie interfejsów API umożliwia dostęp do szerokiej gamy źródeł online, takich jak bazy danych bibliograficznych, repozytoria tekstów historycznych czy media społecznościowe.
Pomysł na warsztat
Niniejszą lekcję można wykorzystać jako wstęp do programowania w R, używając danych z dowolnego API instytucji dziedzictwa. Darmowe konto w ramach Posit.cloud daje dostęp do wszystkich narzędzi w ramach IDE i eliminuje konieczność samodzielnej i skomplikowanej instalacji R i RStudio na własnym komputerze.