Gliwice 09.10.2009 LABORATORIM BIOINFORMATYKI Temat: Język i środowisko programistyczne R Opracowali: Aleksandra Gruca, Łukasz Pracki
Wprowadzenie R jest zarówno językiem programowania jak i środowiskiem przeznaczonym głównie do wykonywania obliczeń statystycznych oraz graficznej prezentacji wyników. Język programowania R wywodzi się z popularnego wśród statystyków języka S/S Plus, a nawet może zostać uznany za jego kolejną implementację. Język R jest językiem interpretowanym,co oznacza, że kod źródłowy napisany w R nie jest kompilowany do postaci wykonywalnej (jak na przykład w programach pisanych w języku C lub C++), ale w trakcie uruchomienia na bieżąco tłumaczony jest przez interpreter do postaci kodu maszynowego i dopiero wtedy uruchomiany. Innym przykładem języka interpretowanego jest M-język wykorzystywany wśrodowisku matlab. Środowisko R może być rozszerzane o dodatkowe funkcje poprzez dołączanie do niego dedykowanych bibliotek (pakietów) funkcji, analogicznie do systemu dodatkowych narzędzi (toolbox ów) wykorzystywanego w środowisku Matlab. Jednym z największych i najbardziej rozbudowanych rozszerzeń R jest pakiet Bioconductor zawierający zestaw funkcji do celów analizy danych biologicznych dotyczących zarówno genomiki, proteomiki jak i analizy sekwencji. Zarówno środowisko R jak i jego rozszerzenie Bioconductor jest dostępne w ramach licencji Open Source. Obsługa pomocy:?nazwa_funkcji wyświetla pomoc dla podanej po? funkcji [?plot] nazwa_funkcji wyświetla kod żródłowy funkcji [plot] help.search(nazwa_funkcji) wyświetla pomoc dla podanej funkcji [help.search(plot)] help.start() uruchamia w domyślnej przeglądarce internetowej pomoc w formacie html. args(nazwa_funkcji) wyświetla listę argumentów danej funkcji [args(plot)] example(nazwa_funkcji) wyśweitla przykłady wywołań poszczególnych funkcji. [example(plot)] Poruszanie się w przestrzeni roboczej: dir() wyświetlenie zawartości pakietu roboczego getwd() wyświetlenie ścieżki aktualnego katalogu roboczego setwd(<ścieżka>) ustala katalog roboczy we wskazanym w parametrze katalogu. [setwd( C:/work/ )] UWAGA: w R dla systemu Windows, przy określaniu ścieżek, należy używać znaku slash / zamiast backslash \. Jeśli użycie \ jest konieczne należy znak ten powtórzyć zamiast \ piszemy \\. Przykładowo: setwd( C:/work/ ) - poprawne
setwd( C:\work\ ) - błędne setwd( C:\\work\\ ) - poprawne Typy zmiennych W środowisku R wszystko czym można operować jest obiektem. Obiekty (zmienne) można podzielić na kilka typów: Liczba (typ numeric) - zmienna liczbowa zarówno typu całkowitego jak i zmiennoprzecinkowego. Charakter zmienna tekstowa (rozpoczynamy znakiem lub ). Zarówno ciąg znaków jak i jeden znak. Typ logiczny zmienna logiczna przyjmuje stany TRUE lub FALSE Wektor - uporządkowany zbiór obiektów tego samego typu. Konstruktorem wektora jest funkcja c. Jeśli chcemy utworzyć wektor zawierający cyfry 3,10.5, 3.2, 7, 3.6 można zrobić to w następujący sposób: x<-c(3,10.5,3.2,7,2.6) x= c(3,10.5,3.2,7,26) assign( x, c(3,10.5,3.2,7,3.6)) Operator strzałki jest często stosowany w języku R, a należy go utożsamiać z nadaniem wartości czyli w powyższych przypadkach jest równoznaczny z operatorem =. Definiując nowy wektor możemy do tego celu wykorzystać zmienne które wcześniej zostały zdefiniowane w przestrzeni roboczej, na przykład: y<-c(x,5,x,8) da w wyniku 12-to elementowy wektor: 3,10.5,3.2,7,3.6,5,3,10.5, 3.2,7,3.6,8 Istnieje również metoda na nadawanie wartości początkowych jako kolejnych elementów ciągu: vec=c(1:100); W środowisku R typy nadawane są zmiennym w momencie przypisania im wartości. Charakter przypisanej wartości determinuje typ. Zmienna może zatem zmieniać swój charakter w trakcie działania skryptu być np.wektorem, później tekstem i ostatecznie pojedynczą wartością: a=c(1,7,6); a= tekst ; a=4; UWAGA: Charaketerystycznym elementem składni języka R jest to że znak kropki jest traktowany jak zwykły znak tekstowy. Oznacza to, że można stworzyć zmienne o nazwach:..a a. a.b
Jest to mylące dla osób które miały już styczność z programowaniem w innycjh językach. Kropka nie jest operatorem ani żadnym znakiem specjalnym jest jednak często używana w nazewnictwie np. dane dane.indeksy dane.nazwy Są to 3 różne zmienne a nie jedna zmienna dane o atrybutach indeksy i nazwy. Bardziej zawansowane struktury danych: Macierze macierze (matrix) macierze są to wektory którym nadano dwa lub więcej wymiarów. Tworzenie macierzy: Do utworzenia macierzy służy funkcja matrix(). Rozmiar macierzy determinowany jest przez parametry jej wywołania. Przykładowo jeśli chcemy utworzyć macierz 2x4 z elementami 1,2,3,4,5,6,7,8 to możebmy posłużyc się poleceniem: dane=c(1:8); z=matrix(dane,2,4) lub krócej bez potrzeby tworzenia dodatkowej zmiennej: z=matrix(c(1:8),2,4) Dane zostaną rozlokowane kolumnami tzn. wartośći 1 i 2 trafią do pierwszej kolumny 3, 4 do drugiej itd. W języku R podobnie jak w środowisku Matab każdy z parametrów ma określoną nazwę. Pozwala to na podawanie parametrów w dowolnej kolejności. Aby sprawdzić nazwy parametrów można wykorzystać poznaną już funkcję args(): args(matrix) Efekt: function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) Jak widać w poprzednim przykładzie mogliśmy odwołać się do parametrów jawnie: z=matrix(data=c(1:8),nrow=2,ncol=4) lub na przykład: z=matrix(nrow=2,ncol=4, data=c(1:8))
Wywołując funkcję nie trzeba podawać wszystkich parametrów. Dlatego też jeśli chcielibyśmy utworzyć pustą macierz bez danych wystarczy zastosować: z=matrix(nrow=2,ncol=4); Odwoływanie się do elementów macierzy: Macierze tak jak i wektory mogą zawierać jedynie elementy jednego typu. Do elementów macierzy odwołuje się podając indeks wiersza i kolumny [wiersz,kolumna]. z[1,4] element znajdujący się na przecięciu pierwszego wiersza i czwartej kolumny. z[7] element 7-y w kolejności tutaj pomijany jest rozmiar macierzy. Aby z wektora stworzyć macierz można wykorzystać funkcję array: z = array(y, c(2,6)) Każda macierz posiada dodatkowy atrybut dimnames, w którym można umieścić nazwy każdej kolumny i każdego wiersza. Atrybut ten jest listą. Listy listy (lists) lista jest strukturą danych, która może zawierać w sobie dowolną ilość zmiennych dowolnego typu. Do elementów listy można odwoływać się poprzez operator [[<indeks>]] albo za pomocą znaku $. Listy znajdują zastosowanie podczas definiowania funkcji, które zwracają wiele zmiennych. Standardowo w języku R funkcje mogą zwracać tylko jedną zmienną, tak więc w przypadku konieczności zwrócenia większej liczby zmiennych można wykorzystać strukturę listy. Tworzenie listy: a<-list(car= Toyota,model= YARIS,V=1.0,colors.available=c( white, blue,black )) Jak widać utworzona lista składa się z 4 pól. Pierwsze i drugie są typu znakowego, kolejne liczbowego natomiast ostatnie jest wektorem 3-elementowym. Ponadto każde z pól ma przypisaną nazwę. Pozwala to na odwoływanie się zarówno operatorem [[]] jak i bardziej obiektowo za pomocą nazwy pola. Odwoływanie się do elementów listy: a[[1]] Toyota a$car Toyota a$model YARIS a$colors.available[2] blue a[[4]][2] blue Znając listy możemy teraz nadać wartość atrybutowi dimnames macierzy z. Ponieważ macierz z ma dwa wiersze i 4 kolumny należy stworzyć listę dwuelementową (pierwsyz element to nazwy wierszy, drugi nazwy kolumn): dimnames(z)=list(c("a","b"),c("c","d","e","f"))
lub bardziej elegancko: dimnames(z)=list(wiersze=c("a","b"),kolumny=c("c","d","e","f")) Ramki Ramka (data.frame) ramki są strukturą podobną do macierzy z tą różnicą, że kolumny mogą być różnego typu. W sytuacji gdy posiadamy zbiór pewnych obserwacji opisanych wieloma atrybutami różnych typów ramka znakomicie oddaje pierwotną strukturę danych. Do elementów ramki można odwołać się zarówno poprzez podanie indeksów wiersza i kolumny jak i za pomocą znaku $. Ramka również posiada dodatkowy atrybut dimnames. Utworzenie ramki: names<-c( Janek, Piotrek, Krzysiek ) ages<-c(10,13,7) boys<-data.frame(names,ages) Częstym sposobem tworzenia ramki jest wczytanie danych z zewnętrznego pliku wykorzystując do tego celu funkcję read.table(). Pliki które można wczytywać muszą mieć strukturę CSV jest to format w którym można zapisywać arkusze Excela co pozwala na komunikacje tych dwóch narzędzi. Funkcja read.table() posiada parametry umożliwiające dopasowanie się do formatu pliku. Przykładowa zawartość pliku jaki można wczytać: dane.txt 1 Rafał 2 Bartek 3 Romek ramka=read.table(file= dane.txt, header=false,sep= \t ); Jak widać można dobrać dowolny separator oraz zawrzeć w pliku np. nazwy kolumn Istnieje również funkcja write.table która pozwala na tworzenie plików CSV: write.table(<dane>,file=<sciezka>,sep=<separator>)zapisanie obiektu typu lista lub tablica do pliku. Wygodnym sposobem przeglądania i edycji obiektów, które są w postaci dużych tabel i macierzy jest użycie funkcji edit(). Powoduje to otwarcie osobnego edytora. Np. edit(ramka) Oprócz powyższych typów istnieją również inne jak np. ExpressionSet z którym będziemy pracować w trakcie zajęć. Obiekty takie mają niekiedy atrybuty. Do nich odwołujemy się poprzez operator @. Np. obiekt@atrybut
Zarządzanie zmiennymi: ls() lista aktualnie zdefiniowanych zmiennych w danej przestrzeni roboczej str(x) wyświetlenie informacji o zmiennej x is(x) wyświetlenie typu zmiennej x as(x,typ) konwersja zmiennej x do typu typ dim(x) wyświetlenie wymiarów zmiennej x length(x) wyświetlenie długości zmiennej x rm(x,y) usunięcie z przestrzeni roboczej zmiennych x i y rm(list=ls(0)) usunięcie z przestrzenie roboczej wszystkich zmiennych i obiektów. To samo można uzyskać poprzez menu :Misc->Remove all objects save.image() zapisanie aktualnej przestrzeni roboczej (wartości zmiennych) do pliku. To samo można uzyskać poprzez menu File->Save workspace. Domyślny plik przestrzeni roboczej to plik.rdata. Zapis danych do pliku cat(x,file= filename,appena=f) zapisanie wektora x do pliku. Podczas laboratoriów będziemy korzystać czasami z już przygotowanych skryptów po prostu plików z ciągami poleceń. Aby korzystać z pliku np. mojefunkcje.r należy użyć funkcji source(): source(<sciezka>) lub przeciągnać plik do okna środowiska R. Wartości specjalne Inf nieskończoność NULL obiekt pusty o długości równej 0 NA logiczna wartość o długości 1 opisująca wartość brakującą (missing value). Zarządzanie pakietami library() lista wszystkich pakietów aktualnie zainstalowanych install.packages(x) pobranie pakietu x (Packages->Install Packages) z serwera na dysk lokalny. library(x) zaimportowanie pakietu x do aktywnej sesji R (funkcje i dane pakietu stają się widoczne - można z nich korzystać) data() wyświetlenie listy wszystkich dostępnych zbiorów danych data(x) wprowadzenie do przestrzeni roboczej zbioru x Bardzo przydatnym sposobem instalacji pakietów BioConductor jest automatyczne ściągnięcie ich z serwera. Wystrczy wydać polecenia: source("http://bioconductor.org/bioclite.r") bioclite(<nazwa_pakietu>)