Bioinformatyka: Wykład 4 R Elementy języka programowania
Pytanie z poprzedniego wkładu podaj polecenie, które dla zbioru iris wyświetli podzbiór składający się z losowej próby wierszy, próba ma mieć liczebność 20 kolumn 1, 3 i 5.! podaj polecenie, które wygeneruje wykres zależności zmiennej Sepal.Width od zmiennej Petal.Length. Należy dodatkowo narysować obiekty kolorem zależnym od klasy (zmienna Species)
WEKTORY LOGICZNE > x10<-runif(10) > x10 [1] 0.05399084 0.53993393 0.60492961 0.17366489 0.74624543 0.39407939 0.18500973 0.92854452 0.49957395 0.02079991 > x10>0.5 [1] FALSE TRUE TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE!! > x10>0.5 ->Mask > Mask [1] FALSE TRUE TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE > str(mask) logi [1:10] FALSE TRUE TRUE FALSE TRUE FALSE...
WEKTORY LOGICZNE > x10[mask] [1] 0.5399339 0.6049296 0.7462454 0.9285445 > x10[x10>0.5] [1] 0.5399339 0.6049296 0.7462454 0.9285445! > which(mask) [1] 2 3 5 8 > which(x10>0.5) [1] 2 3 5 8
WEKTORY ZNAKOWE Pojedynczy napis jest typem podstawowym. Można utworzyć wektory z napisów. Pojedynczy napis NIE JEST wektorem znaków > napis<-"bioinformatyka" > napis [1] "Bioinformatyka" > napis2<c("b","i","o","i","n","f","o","r","m","a","t","y","k","a") > napis2 [1] "B" "i" "o" "i" "n" "f" "o" "r" "m" "a" "t" "y" "k" "a" > napis3<-c("bio","in","for","ma","ty","ka") > napis3 [1] "Bio" "in" "for" "ma" "ty" "ka"
WEKTORY ZNAKOWE Pojedynczy napis jest typem podstawowym. Można utworzyć wektory z napisów. Pojedynczy napis NIE JEST wektorem znaków > str(napis) chr "Bioinformatyka" > str(napis2) chr [1:14] "B" "i" "o" "i" "n" "f" "o" "r" "m" "a" "t" "y" "k" "a" > str(napis3) chr [1:6] "Bio" "in" "for" "ma" "ty" "ka" > napis2[3] [1] "o" > napis3[3] [1] "for" > napis[3] [1] NA
WEKTORY ZNAKOWE Sklejanie napisów > napis4<-c("b","io","inf","orma","tyka ") > napis4 [1] "B" "io" "inf" "orma" "tyka " > str(napis4) chr [1:5] "B" "io" "inf" "orma" "tyka! > napis2 [1] "B" "i" "o" "i" "n" "f" "o" "r" "m" "a" "t" "y" "k" "a" > paste(napis2,collapse="") [1] "Bioinformatyka" > paste(napis2,collapse=" ") [1] "B i o i n f o r m a t y k a" > paste(napis2,collapse="-") [1] "B-i-o-i-n-f-o-r-m-a-t-y-k-a"
WEKTORY ZNAKOWE Sklejanie napisów > AA<-c("a","aa","aaa","aaaa","aaaaa","aaaaaa") > BB<-c("b","bb") > paste(aa,bb) [1] "a b" "aa bb" "aaa b" "aaaa bb" [5] "aaaaa b" "aaaaaa bb" > paste(aa,bb,sep="-") [1] "a-b" "aa-bb" "aaa-b" [5] "aaaa-bb" "aaaaa-b" "aaaaaa-bb" > paste(aa,nb,sep="-",collapse=" ") [1] "a-b aa-bb aaa-b aaaa-bb aaaaa-b aaaaaa-bb" > paste(aa,bb,sep="-",collapse="") [1] "a-baa-bbaaa-baaaa-bbaaaaa-baaaaaa-bb"
WEKTORY ZNAKOWE Rozdzielanie napisów - wynik jest listą. > nchar("bioinformatyka") [1] 14 > getwd()-> MyPath > strsplit(mypath,"/") [[1]] [1] "" "Users" "rudnicki" "Documents""dydaktyka" "Bioinformatics" [7] "Białystok" > strsplit(mypath,"/")->mydirectories > nchar(mydirectories) [1] 83 > length(mydirectories) [1] 1 > unlist(mydirectories) [1] "" "Users" "rudnicki" "Documents" "dydaktyka" "Bioinformatics" [7] "Białystok" > nchar(unlist(mydirectories)) [1] 0 5 8 9 9 14 9
CZAS >> Sys.time() [1] "2015-05-17 12:23:11 CEST" > options(digits.secs=2) > Sys.time() [1] "2015-05-17 12:23:42.87 CEST"
CZAS Dwa sposoby reprezentacji czasu: Klasa POSIXct liczba sekund od początku epoki komputerowej Klasa POSIXlt lista pól określających czas
Pola klasy POSIXlt: sec 0 61: sekundy min 0 59: minuty hour 0 23: godziny mday 1 31: dzień miesiąca CZAS mon 0 11: liczba miesięcy, jaka upłynęła od pierwszego miesiąca w roku year lata od roku 1900. wday 0 6 dni tygodnia, zaczynające się w niedzielę yday 0 365: dzień roku. isdst flaga czasu letniego. 1 prawda, 0 - fałsz, ujemna jeśli nie wiadomo. zone strefa czasowa, domyślnie - czyli UTC gmtoff przesunięcie w sekundach względem GMT
CZAS Na zmiennych czasowych możemy prowadzić proste obliczenia przedziałów czasowych. Należy pamiętać, że czas nie jest w R zwykłą liczbą - ani całkowitą ani rzeczywistą > start.time<-sys.time() > end.time<-sys.time() > interval <- end.time-start.time > interval Time difference of 6.071554 secs > interval2 <- 2*interval > interval^2 Error in Ops.difftime(interval, 2) : '^' nie jest określone dla obiektów klasy "difftime"
CZAS Na zmiennych typu czasowego można wykonywać jedynie operację odejmowania. Wynikiem jest obiekt klasy przedział czasu > start.time<-sys.time() > end.time<-sys.time() > interval <- end.time-start.time > end.time.2<- Sys.time() > interval2 <- end.time.2-end.time > interval2 Time difference of 1.181538 mins > interval2-interval Time difference of 64.82073 secs > interval2-10*interval Time difference of 10.17675 secs > interval2*interval Error in `*.difftime`(interval2, interval) : oba argumenty operatora '*' nie mogą być obiektami klasy "difftime"
CZAS Na zmiennych typu czasowego można wykonywać jedynie operację odejmowania. Wynikiem jest obiekt klasy przedział czasu > interval2+interval Time difference of 76.96384 secs > start.time+end.time Error in `+.POSIXt`(start.time, end.time) : dwuargumentowy operator '+' nie jest określony dla obiektów klasy "POSIXt" Obiekty typu przedział czasu można dodawać i odejmować. Wynikiem jest obiekt klasy przedział czasu. Nie można dodawać do siebie obiektów klasy czas.
KONWERSJE TYPÓW as.posixlt() - Rzutowanie obiektu na typ POSIXlt. Jeżeli argument jest liczbą, to koniecznie trzeba podać punkt startu, od którego liczony jest czas > z <- as.posixlt(sys.time()) > z [1] "2015-05-17 13:12:30.37 CEST" > as.posixlt(1435555555,tz="cet",origin="1970-01-02 00:00:00") [1] "2015-06-30 07:25:55 CEST" > as.posixlt(-1435555555,tz="cet",origin="1970-01-02 00:00:00") [1] "1924-07-06 19:34:05 CET"!
KONWERSJE TYPÓW unclass() - Rzutowanie obiektu specyficznego typu na typ podstawowy > zlt <- as.posixlt(sys.time()) > zct <- Sys.time() > zlt [1] "2015-05-17 13:12:30.37 CEST" > zct [1] "2015-05-17 13:12:39.48 CEST" > mode(zct) [1] "numeric" > unclass(zct) [1] 1449351685 > mode(zlt) [1] "list" > unclass(zlt)
KONWERSJE TYPÓW unclass() - Rzutowanie obiektu specyficznego typu na typ podstawowy > zlt <- as.posixlt(sys.time()) > zct <- Sys.time() > zlt [1] "2015-05-17 13:12:30.37 CEST" > zct [1] "2015-05-17 13:12:39.48 CEST" > mode(zct) [1] "numeric" > unclass(zct) [1] 1449351685 > mode(zlt) [1] "list" > unclass(zlt) $sec [1] 40.83431 $min [1] 56 $hour [1] 20 $mday [1] 5 $mon [1] 11 $year [1] 115 $wday [1] 6 $yday [1] 338 $isdst [1] 0 $zone [1] "CET" $gmtoff [1] 3600 attr(,"tzone") [1] "" "CET" "CEST"
KONWERSJE TYPÓW unlist() - rzutowanie listy na wektor > zlt <- as.posixlt(sys.time()) > zlt [1] "2015-05-17 13:12:39.48 CEST" > unlist(zlt) sec min hour mday "17.4575378894806" "41" "22" "5" mon year wday yday "11" "115" "6" "338" isdst zone gmtoff "0" "CET" "3600"
PRIORYTET OPERATORÓW [ [[ - Indeksowanie $ @ - dostęp do pól, składowych ^ ** - potęgowanie - + - operatory unarne : - generowanie sekwencji %coś% operatory specjalne * / - mnożenie, dzielenie + - - dodawanie, odejmowanie ==!= < > <= >=! - negacja logiczna
PRIORYTET OPERATORÓW! - negacja logiczna & && iloczyn logiczny (wektorowy i skalarny)* - suma logiczna (wektorowo i skalarnie)* ~ - zależność w formule -> ->> przypisanie w prawo = <-? - przypisanie (z prawej w lewą) - przypisanie (z prawej w lewą) - pomoc! * operacje & oraz wykonujemy wektorowo, natomiast && oraz służą do tworzenia warunków w instrukcjach warunkowych if, ifelse, while.
DEFINIOWANIE FUNKCJI Funkcja jest definiowana przy pomocy słowa kluczowego function. Jest obiektem, który może być przypisywany na zmienną, może być argumentem innej funkcji, elementem listy, wektora itp. > AddNumbers <- function(a,b){ c <- a+b return(c) } > AddNumbers(3,5) [1] 5
DEFINIOWANIE FUNKCJI Funkcja jest definiowana przy pomocy słowa kluczowego function. Argumenty są przekazywane przez wartość Zmienne są lokalne i znikają po wykonaniu funkcji Każda funkcja zwraca wynik, wartością wyniku jest wartość ostatneiego wyrażenia w funkcji. Możemy (i należy dla jasności) użyć słowa kluczowego return Można zdefiniować anonimową funkcję w miejscu jej wykonania. > apply(myarray,2, function(x) sd(x)/mean(x) )
UNIKANIE PROSTYCH BŁĘDÓW Piszemy nawiasy przy wołaniu funkcji > ls function (name, pos = -1L, envir = as.environment(pos), all.names = FALSE, pattern, sorted = TRUE) { if (!missing(name)) { } } <bytecode: 0x7ff01017d7c0> <environment: namespace:base> > ls() [1] "AddNumbers" "ddz" "dz" "end.time" "end.time. 2" "interval" "interval2" "Iris" "iris.lm"
UNIKANIE PROSTYCH BŁĘDÓW Przy podawaniu ścieżek w Windows piszemy podwóje ukośniki (backslash) >! MyData<- read.csv( D:\\data\\MyLab\\example.csv )! ukośnik \ ma specjalne znaczenie (escape character) i dlatego do zapisania samego ukośnika musimy użyć dwóch
UNIKANIE PROSTYCH BŁĘDÓW Uważajmy na niepotrzebne spacje > x < -pi BŁĄD: nie znaleziono obiektu 'x' > x<-3.14 > x < -pi [1] FALSE > x <- pi > x [1] 3.141593
UNIKANIE PROSTYCH BŁĘDÓW Uważajmy na komendy edytowane w wielu liniach! > x <- 1 + 2 + 3 +! + 4 + 5 >! x [1] 15 >! x <- 1 + 2 + 3 >! +4 +5 [1] 9 >! x [1] 6! Uważajmy na operatory = i ==! > x = 1 + 2 + 3 + > x == 1 + 2 + 3 +
UNIKANIE PROSTYCH BŁĘDÓW Pamiętajmy jakie argumenty przyjmują funkcje > mean(3,4,5) #funkcja z jednym argumentem [1] 3 > mean(c(3,4,5)) #argument ma być wektorem [1] 4 > max(3,4,5) # funkcja przyjmuje wiele argumentów [1] 5 > max(1:3,2:4) [1] 4 > pmax(1:3,2:4) # funkcja liczy warunek wektorowo [1] 2 3 4 > min(1:3,2:4) [1] 1 > pmin(1:3,2:4) [1] 1 2 3
KATALOG ROBOCZY Funkcje do wypisania i zmiany katalogu roboczego getwd() - GET Work Directory setwd() - SET Work Directory > getwd() [1] "/Users/rudnicki" > setwd("documents/dydaktyka/bioinformatics/") > getwd() [1] "/Users/rudnicki/Documents/dydaktyka/Bioinformatics" > setwd("/users/rudnicki/documents/dydaktyka/") > getwd() [1] "/Users/rudnicki/Documents/dydaktyka/"
OBSŁUGA PAKIETÓW Funkcje search() - wypisuje pakiety załadowane do pamięci library( LibName ) - ładuje pakiet o nazwie LibName, wywołana bez argumentu wypisuje zainstalowane pakiety require( LibName ) - ładuje bibliotekę o nazwie LibName jeśli jest potrzebna w skrypcie (generuje ostrzeżenie zamiast błędu jeśli biblioteki nie ma) detach(package:whatever) - usuwa pakiet whatever z przestrzeni roboczej sesji R install.packages( PackageName ) - instaluje bibliotekę o nazwie PackageName z serwera CRAN (użytkownik jest proszony o podanie serwera CRAN z listy)
OBSŁUGA PAKIETÓW > search() [1] ".GlobalEnv" "package:randomforest" "tools:rgui" [4] "package:stats" "package:graphics" "package:grdevices" [7] "package:utils" "package:datasets" "package:methods" [10] "Autoloads" "package:base" > library("boruta") Ładowanie wymaganego pakietu: rferns > search() [1] ".GlobalEnv" "package:boruta" "package:rferns" [4] "package:randomforest" "tools:rgui" "package:stats" [7] "package:graphics" "package:grdevices" "package:utils" [10] "package:datasets" "package:methods" "Autoloads" [13] "package:base" > detach(package:boruta) > detach(package:rferns) > search() [1] ".GlobalEnv" "package:randomforest" "tools:rgui" [4] "package:stats" "package:graphics" "package:grdevices" [7] "package:utils" "package:datasets" "package:methods" [10] "Autoloads" "package:base"
OBSŁUGA PAKIETÓW > install.packages("rferns") Installing package into /Users/rudnicki/Library/R/3.2/library (as lib is unspecified) --- Proszę wybrać serwer lustrzany CRAN do użycia w tej sesji --- Jest dostępna wersja binarna ale wersja ze źródłami jest późniejsza: binary source needs_compilation rferns 1.1.0 2.0.0 TRUE Do you want to install from sources the package which needs compilation? y/n: y installing the source package rferns! próbowanie adresu URL 'http://cran.wu.ac.at/src/contrib/rferns_2.0.0.tar.gz' Content type 'application/x-gzip' length 19055 bytes (18 KB) ================================================== downloaded 18 KB * installing *source* package rferns... ** pakiet rferns został pomyślnie rozpakowany oraz sumy MD5 zostały sprawdzone ** libs
OBSŁUGA PAKIETÓW > install.packages("rferns") clang -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I/usr/local/ include -I/usr/local/include/freetype2 -I/opt/X11/include -fpic -Wall - mtune=core2 -g -O2 -c ferns.c -o ferns.o clang -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup - single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/ Resources/lib -L/usr/local/lib -o rferns.so ferns.o -F/Library/Frameworks/ R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation installing to /Users/rudnicki/Library/R/3.2/library/rFerns/libs ** R ** inst ** preparing package for lazy loading ** help *** installing help indices ** building package indices ** testing if installed package can be loaded * DONE (rferns) Pobrane pakiety źródłowe są w /private/var/folders/4j/lyt_c98s1b147vfnlq9h2hrc0000gp/t/rtmp4zxgm0/ downloaded_packages >
WCZYTYWANIE DANYCH Uwaga ogólna - R nie jest najlepszym narzędziem do pracy z plikami tekstowymi. To wynik zastosowania w praktyce filozofii Uniksa - skoro istnieje mnóstwo innych narzędzi doskonale nadających się do obróbki plików tekstowych, to nie zajmujmy się tym zadaniem, użyjmy do obróbki tekstu np. awk, sed, perl, python itp.
WCZYTYWANIE DANYCH funkcje R do czytania danych spodziewają się danych w postaci tabeli i wczytują je do ramki danych (data.frame) read.table() read.csv(), read.csv2() read.ftable() read.delim(), read.delim2() Zapisywanie danych w wersji tekstowej write.csv() write.table()
WCZYTYWANIE DANYCH - EXCEL Dane występują często w formacie XLS lub XLSX Standardowy R nie obsługuje tych formatów, ale można: 1. Skopiować dane do schowka i użyć funkcji read.table( clipboard ) 2. Zapisać dane z excela do pliku CSV i użyć funkcji read.csv() 3. Użyć pakietu gdata require(gdata) df = read.xls ("myfile.xlsx"), sheet = 1, header = TRUE) 4. Użyć pakietu XLConnect require(xlconnect) wb = loadworkbook("myfile.xlsx") df = readworksheet(wb, sheet = "Sheet1", header = TRUE) 5. Użyć pakietu xlsx require(xlsx) read.xlsx("myfile.xlsx", sheetname = Sheet1") #read.xlsx2( myfile.xlsx", sheetname = "Sheet1")
PLIKI RDATA Natywny format plików danych R Obsługiwany funkcjami load() save() > ls() [1] "interval2" "Iris" "iris.lm" "iris10" "my.table" "MySample" [7] "rownames" > save(my.table,file="giss.rdata") > rm(my.table) > ls() [1]"interval2" "Iris" "iris.lm" "iris10" "MySample" "rownames" > load("giss.rdata") > ls() [1] ""interval2" "Iris" "iris.lm" "iris10" "my.table" "MySample" [7] "rownames"
OPERACJE NA RAMKACH Łączenie ramek danych cbind(df1,df2,df3, ) - Column bind - dołącza do df1 kolumny z df2, df3 itd. Wynik jest nową ramką o liczbie kolumn równej sumie liczb kolumn ramek wejściowych. rbind(df1,df2,df3, ) - Row bind - dołącza do df1 wiersze z df2, df3 itd. Wynik jest nową ramką o liczbie wierszy równiej sumie liczb wierszy w ramkach wejściowych merge(df1,df2, ) - łączy ramki według wspólnej kolumny do df1 wiersze z df2, df3 itd. Wynik jest nową ramką o liczbie wierszy równiej sumie liczb wierszy w ramkach wejściowych. Polecenie analogiczne do operacji join w SQL.
OPERACJE NA RAMKACH Ułatwienie w przywoływaniu kolumn with(dfname, ) - operacje przeprowadzone w nawiasie na kolumnach ramki nie muszą odwoływać się do nazwy ramki. attach(dfname) - kolumny ramki są dołączone do przestrzeni nazw w ramach sesji. > head(giss.temp) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 1 1880-29 -19-17 -27-13 -28-22 -6-16 -15-18 -20 2 1881-8 -13 2-2 -3-27 -5-1 -8-18 -25-14 > tail(giss.temp) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 135 2014 74 51 77 79 86 66 58 82 90 86 68 79 136 2015 82 88 91 75 79 78 75 81 80 104 ** **
OPERACJE NA RAMKACH Ułatwienie w przywoływaniu kolumn > with(giss.temp,as.numeric(as.character(nov)))->giss.temp$nov Warning message: In eval(expr, envir, enclos) : pojawiły się wartości NA na skutek przekształcenia > with(giss.temp,as.numeric(as.character(dec)))->giss.temp$dec Warning message: In eval(expr, envir, enclos) : pojawiły się wartości NA na skutek przekształcenia > tail(giss.temp) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 136 2015 82 88 91 75 79 78 75 81 80 104 NA NA
OPERACJE NA RAMKACH Ułatwienie w przywoływaniu kolumn > GISS.temp$Q1<-with(GISS.temp,(Jan+Feb+Mar)/3) > GISS.temp$Q2<-with(GISS.temp,(Apr+May+Jun)/3) > GISS.temp$Q3<-with(GISS.temp,(Jul+Aug+Sep)/3) > GISS.temp$Q4<-with(GISS.temp,(Oct+Nov+Dec)/3) > GISS.temp$Mean<-with(GISS.temp,(Q1+Q2+Q3+Q4)/4) > head(giss.temp) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Q1 Q2 Q3 Q4 Mean 1 1880-29 -19-17 -27-13 -28-22 -6-16 -15-18 -20-21.67-22.67-14.67-17.67 19.17 > tail(giss.temp) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Q1 Q2 Q3 Q4 Mean 134 2013 67 57 65 54 61 65 59 66 77 70 81 67 63.00 60.00 67.33 72.67 65.75 135 2014 74 51 77 79 86 66 58 82 90 86 68 79 67.33 77.00 76.67 77.67 74.67 136 2015 82 88 91 75 79 78 75 81 80 104 NA NA 87.00 77.33 78.67 NA NA
OPERACJE NA RAMKACH > apply(giss.temp[,1:13],2,max,na.ommit=true) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2015 97 89 92 87 86 78 75 82 90 104 NA NA > tail(giss.temp[,1:13],5) Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2011 50 51 64 66 53 59 74 73 56 67 56 53 2012 45 49 57 69 76 62 56 64 75 79 74 52 2013 67 57 65 54 61 65 59 66 77 70 81 67 2014 74 51 77 79 86 66 58 82 90 86 68 79 2015 82 88 91 75 79 78 75 81 80 104 NA NA > apply(giss.temp[,14:17],2,max,na.ommit=true) Q1 Q2 Q3 Q4 87.00000 77.33333 78.66667 NA > tail(giss.temp[,14:17],5) Q1 Q2 Q3 Q4 132 55.00000 59.33333 67.66667 58.66667 133 50.33333 69.00000 65.00000 68.33333 134 63.00000 60.00000 67.33333 72.66667 135 67.33333 77.00000 76.66667 77.66667 136 87.00000 77.33333 78.66667 NA
OPERACJE NA RAMKACH > GISS.temp[123:136,c(1,14:17)] Year Q1 Q2 Q3 Q4 123 2002 80.333333 59.6666667 60.0000000 52.6666667 124 2003 61.333333 55.3333333 62.6666667 68.0000000 125 2004 64.666667 48.6666667 41.6666667 63.6666667 126 2005 66.666667 66.6666667 68.6666667 74.3333333 127 2006 64.000000 53.3333333 63.3333333 73.6666667 128 2007 79.000000 67.6666667 62.6666667 55.6666667 129 2008 46.000000 50.6666667 56.3333333 63.0000000 130 2009 56.333333 64.0000000 70.0000000 69.3333333 131 2010 81.333333 75.3333333 62.3333333 66.3333333 132 2011 55.000000 59.3333333 67.6666667 58.6666667 133 2012 50.333333 69.0000000 65.0000000 68.3333333 134 2013 63.000000 60.0000000 67.3333333 72.6666667 135 2014 67.333333 77.0000000 76.6666667 77.6666667 136 2015 87.000000 77.3333333 78.6666667 NA
RAMKA DANYCH Wg Paul Teetor R Cookbook, O Reilly 2011 Dla statystyka Tablica obserwacji. Wiersz zawiera obserwację, kolumna zmienne. Można odwoływać się do kolumn po numerze lub po nazwie. Dla programisty SQL Tablica, rezydująca w pamięci. Można ją zapisać do pliku, nie trzeba deklarować typów danych - R robi to automatycznie Dla użytkownika Excela Arkusz kalkulacyjny. Bardziej ograniczony bo komórki muszą mieć określony typ, taki sam w całej kolumnie. Dla użytkownika SAS Dla programisty R Dla informatyka Dla managera
RAMKA DANYCH Wg Paul Teetor R Cookbook, O Reilly 2011 Dla statystyka Dla programisty SQL Dla użytkownika Excela Dla użytkownika SAS Odpowiednik dataset. Można ją zapisać do pliku, ale w trakcie operacji musi rezydować w pamięci operacyjnej. Dla programisty R Hybrydowa struktura danych, pośrednia między tablicą a listą. Może zawierać liczby, napisy i faktory, nie można ich mieszać w jednej kolumnie. Można na niej prowadzić działania jak na macierzy. Jest również listą kolumn - można się do niej odwoływać operatorami działającymi na listach. Dla informatyka Dla managera
RAMKA DANYCH Wg Paul Teetor R Cookbook, O Reilly 2011 Dla statystyka Dla programisty SQL Dla użytkownika Excela Dla użytkownika SAS Dla programisty R Dla informatyka Prostokątna struktura danych. Kolumny mają określony typ (numeryczny, znakowy lub faktor), Kolumny muszą mieć etykiety, wiersze mogą mieć etykiety. Można ją indeksować numerycznie (numer wiersza/kolumny) lub według nazw (odpowiednio wierszy i kolumn). Można również używać operatorów listowych do operowanie na kolumnach - można traktować ją jako listę kolumn. Dla managera Możesz tam zapisywać liczby i nazwy. To jest łatwe - to taka mała baza danych. Twoi pracownicy będą zachwyceni używając ramek danych.
RODZINA FUNKCJI APPLY apply() lapply() sapply() tapply() mapply() oraz podobne zastosowanie by()
RODZINA FUNKCJI APPLY lapply() - argumentem jest lista, wynikiem też jest lista. sapply() - argumentem jest lista, wynikiem jest wektor - jeżeli tylko to możliwe. > lapply(iris[,1:4],mean) $Sepal.Length [1] 5.843333 $Sepal.Width [1] 3.057333 $Petal.Length [1] 3.758 $Petal.Width [1] 1.199333 > sapply(iris[,1:4],mean) Sepal.Length Sepal.Width Petal.Length Petal.Width 5.843333 3.057333 3.758000 1.199333
RODZINA FUNKCJI APPLY apply() - argumentem jest macierz, wynikiem wektor, można ją stosować do macierzy i list, ale lista musi mieć wszystkie kolumny tego samego typu. > sapply(iris[,1:4],mean) Sepal.Length Sepal.Width Petal.Length Petal.Width 5.843333 3.057333 3.758000 1.199333! > apply(iris[,1:4],2,mean) Sepal.Length Sepal.Width Petal.Length Petal.Width 5.843333 3.057333 3.758000 1.199333! > apply(iris[,1:4],1,mean)->iris.mean.dim > iris.mean.dim[c(1:5,51:55,101:105)] [1] 2.550 2.375 2.350 2.350 2.550 4.075 3.900 4.100 3.275 3.850 4.525 3.875 4.525 4.150 4.375
RODZINA FUNKCJI APPLY tapply() - argumentem jest wektor, i faktor użyty do grupowania tego wektora, wynikiem jest wektor o długości równej liczbie unikatowych wartości faktora > tapply(iris[,1],iris$species,mean) setosa versicolor virginica 5.006 5.936 6.588 > tapply(iris[,2],iris$species,mean) setosa versicolor virginica 3.428 2.770 2.974 > tapply(iris[,3],iris$species,mean) setosa versicolor virginica 1.462 4.260 5.552 > tapply(iris[,4],iris$species,mean) setosa versicolor virginica 0.246 1.326 2.026
RODZINA FUNKCJI APPLY tapply() - argumentem jest wektor, i faktor użyty do grupowania tego wektora, wynikiem jest wektor o długości równej liczbie unikatowych wartości faktora -------------------------------------------------------------------- > by(iris[,1:4],iris$species,summary) iris$species: setosa Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100 1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200 Median :5.000 Median :3.400 Median :1.500 Median :0.200 Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246 3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300 Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600 ---------------
RODZINA FUNKCJI APPLY > by(iris[,1:4],iris$species,summary) iris$species: versicolor Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.000 Min. :3.00 Min. :1.000 1st Qu.:5.600 1st Qu.:2.525 1st Qu.:4.00 1st Qu.:1.200 Median :5.900 Median :2.800 Median :4.35 Median :1.300 Mean :5.936 Mean :2.770 Mean :4.26 Mean :1.326 3rd Qu.:6.300 3rd Qu.:3.000 3rd Qu.:4.60 3rd Qu.:1.500 Max. :7.000 Max. :3.400 Max. :5.10 Max. :1.800 -------------------------------------------------------------- iris$species: virginica Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.200 Min. :4.500 Min. :1.400 1st Qu.:6.225 1st Qu.:2.800 1st Qu.:5.100 1st Qu.:1.800 Median :6.500 Median :3.000 Median :5.550 Median :2.000 Mean :6.588 Mean :2.974 Mean :5.552 Mean :2.026 3rd Qu.:6.900 3rd Qu.:3.175 3rd Qu.:5.875 3rd Qu.:2.300 Max. :7.900 Max. :3.800 Max. :6.900 Max. :2.500
RODZINA FUNKCJI APPLY > by(iris[,1:4],iris$species,summary) iris$species: setosa Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100 1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200 Median :5.000 Median :3.400 Median :1.500 Median :0.200 Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246 3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300 Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600 ----------------------------------------------------------------------------------- iris$species: versicolor Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.000 Min. :3.00 Min. :1.000 1st Qu.:5.600 1st Qu.:2.525 1st Qu.:4.00 1st Qu.:1.200 Median :5.900 Median :2.800 Median :4.35 Median :1.300 Mean :5.936 Mean :2.770 Mean :4.26 Mean :1.326 3rd Qu.:6.300 3rd Qu.:3.000 3rd Qu.:4.60 3rd Qu.:1.500 Max. :7.000 Max. :3.400 Max. :5.10 Max. :1.800 ----------------------------------------------------------------------------------- iris$species: virginica Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.200 Min. :4.500 Min. :1.400 1st Qu.:6.225 1st Qu.:2.800 1st Qu.:5.100 1st Qu.:1.800 Median :6.500 Median :3.000 Median :5.550 Median :2.000 Mean :6.588 Mean :2.974 Mean :5.552 Mean :2.026 3rd Qu.:6.900 3rd Qu.:3.175 3rd Qu.:5.875 3rd Qu.:2.300 Max. :7.900 Max. :3.800 Max. :6.900 Max. :2.500
RODZINA FUNKCJI APPLY > by(iris[,1:4],iris$species,summary) iris$species: setosa Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100 1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200 Median :5.000 Median :3.400 Median :1.500 Median :0.200 Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246 3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300 Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600 ----------------------------------------------------------------------------------- iris$species: versicolor Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.000 Min. :3.00 Min. :1.000 1st Qu.:5.600 1st Qu.:2.525 1st Qu.:4.00 1st Qu.:1.200 Median :5.900 Median :2.800 Median :4.35 Median :1.300 Mean :5.936 Mean :2.770 Mean :4.26 Mean :1.326 3rd Qu.:6.300 3rd Qu.:3.000 3rd Qu.:4.60 3rd Qu.:1.500 Max. :7.000 Max. :3.400 Max. :5.10 Max. :1.800 ----------------------------------------------------------------------------------- iris$species: virginica Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.200 Min. :4.500 Min. :1.400 1st Qu.:6.225 1st Qu.:2.800 1st Qu.:5.100 1st Qu.:1.800 Median :6.500 Median :3.000 Median :5.550 Median :2.000 Mean :6.588 Mean :2.974 Mean :5.552 Mean :2.026 3rd Qu.:6.900 3rd Qu.:3.175 3rd Qu.:5.875 3rd Qu.:2.300 Max. :7.900 Max. :3.800 Max. :6.900 Max. :2.500
STYL!= MODA Styl programowania jest ważny: przejrzysty i spójny styl sprzyja unikaniu prostych błędów zrozumieniu kodu skłania ku tworzeniu właściwych struktur Trzymanie się ogólnie przyjętych reguł ułatwia życie programiście i użytkownikom zwalnia od wymyślania własnych reguł ułatwia jego wykorzystanie w innych programach Innym Programistom dwa (dni/tygodnie/miesiące/lata) po napisaniu kodu Ty też będziesz Innym Programistą
STYL!= MODA Podstawowe reguły przyjęte w społeczności R Nazwy plików powinny być informatywne i mieć rozszerzenie.r dobre linear_fit.r cross_validated_randomforest.r złe aaa.r fun1.r Jeżeli w skrypcie będą wykorzystywane w ustalonej kolejności dodaj numer PRZED nazwą 0-init_data_structures.R 1-read_data.R 2-do_calculations.R
Nazywanie zmiennych STYL!= MODA Nazwy zmiennych i funkcji powinny być pisane małymi literami powinny być opisowe - nazwa funkcji powinna zawierać czynności, nazwa zmiennej odnosić się do zawartości. Nazwy muszą być krótkie nazwy składające się z wielu wyrazów łączymy podkreśleniami. dopuszczalny jest tzw CamelCase - ale to jest gorsze rozwiązanie. jeżeli istnieje choć minimalna szansa, że kod będzie używany międzynarodowo, piszemy po angielsku dobrze start_day, last_day złe first_day_of_the_pneumonia_study day1.
Światło - więcej światła STYL!= MODA w definicjach fukcji przechodzimy do nowej lini po nawiasie klamrowym, zawsze używamy nawiasów klamrowych w definicji funkcj zamykamy blok tekstu nawiasem klamrowym w oddzialnej linii, do wcinania kodu używamy spacji (zwyczajowo dwie spacje) operatory otaczamy spacjami (zarówno operacje arytmetyczne, jak i przypisywanie i porównania. Nawiasy, oddzielamy od innego tekstu spacjami, za wyjątkiem wywołań funkcji długość linii - staraj się ograniczać do 80 linii. Jeśli często używasz wiecej znaków w linii to znaczy, że czegoś nie nie można uprościć - zdefiniować powtarzalne funkcje.