diff --git a/be/r.md b/be/r.md new file mode 100644 index 0000000000..c037315a46 --- /dev/null +++ b/be/r.md @@ -0,0 +1,815 @@ +--- +name: R +contributors: + - ["e99n09", "http://github.com/e99n09"] + - ["isomorphismes", "http://twitter.com/isomorphisms"] + - ["kalinn", "http://github.com/kalinn"] + - ["mribeirodantas", "http://github.com/mribeirodantas"] +translators: + - ["lucii7vel", "https://github.com/lucii7vel"] +filename: learnr.r +--- + +R - гэта статыстычная мова праграмавання. Яна мае шмат бібліятэк для +загрузкі і ачысткі даных, запуску статыстычных працэдур і стварэння +графікаў. Вы таксама можаце запускаць каманды `R` унутры LaTeX дакумента. + +```r +# Каментарыі пачынаюцца са знака рашоткі, таксама вядомага як знак нумара (#). + +# Вы не можаце рабіць шматрадковыя каментарыі, +# але можаце стагаваць некалькі каментарыяў такім чынам. + +# на Windows вы можаце выкарыстоўваць CTRL-ENTER каб выканаць радок. +# на Mac гэта COMMAND-ENTER + + + +############################################################################# +# Рэчы, якія вы можаце рабіць не разумеючы нічога пра праграмаванне +############################################################################# + +# У гэтай секцыі мы пакажам некаторыя выдатныя рэчы, якія вы можаце +# рабіць у R не разумеючы нічога пра праграмаванне. Не хвалюйцеся, +# калі не разумееце штосьці з таго, што робіць код. Атрымлівайце асалоду! + +data() # агляд падрыхтаваных датасэтаў +data(rivers) # агляд наступнага: "Даўжыня галоўных рэк Паўночнай Амерыкі" +ls() # заўважце, што ў працоўнай прасторы цяпер ёсць "rivers" +head(rivers) # заглянуць у датасэт +# 735 320 325 392 524 450 + +length(rivers) # колькі рэк было вымерана? +# 141 +summary(rivers) # якая зводная статыстыка? +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 135.0 310.0 425.0 591.2 680.0 3710.0 + +# зрабіць графік "сцябло і лісце" (прадстаўленне даных у якасці гістаграмы) +stem(rivers) + +# Дзесятковая кропка - 2 лічбы справа ад | +# +# 0 | 4 +# 2 | 011223334555566667778888899900001111223333344455555666688888999 +# 4 | 111222333445566779001233344567 +# 6 | 000112233578012234468 +# 8 | 045790018 +# 10 | 04507 +# 12 | 1471 +# 14 | 56 +# 16 | 7 +# 18 | 9 +# 20 | +# 22 | 25 +# 24 | 3 +# 26 | +# 28 | +# 30 | +# 32 | +# 34 | +# 36 | 1 + +stem(log(rivers)) +# Заўважце, што даныя размеркаваны ані нармальна, ані логнармальна! +# З'ешце, прыхільнікі званавіднай крывой. + +# Дзесятковая кропка - 1 лічба злева ад | +# +# 48 | 1 +# 50 | +# 52 | 15578 +# 54 | 44571222466689 +# 56 | 023334677000124455789 +# 58 | 00122366666999933445777 +# 60 | 122445567800133459 +# 62 | 112666799035 +# 64 | 00011334581257889 +# 66 | 003683579 +# 68 | 0019156 +# 70 | 079357 +# 72 | 89 +# 74 | 84 +# 76 | 56 +# 78 | 4 +# 80 | +# 82 | 2 + +# зрабіць гістаграму: +hist(rivers, col = "#333333", border = "white", breaks = 25) +hist(log(rivers), col = "#333333", border = "white", breaks = 25) +# пагуляйцеся з параметрамі, зробіце больш графікаў пазней + +# Вось іншы элегантны датасэт, адзін з падрыхтаваных. У R такіх шмат. +data(discoveries) +plot(discoveries, col = "#333333", lwd = 3, xlab = "Year", + main="Number of important discoveries per year") +plot(discoveries, col = "#333333", lwd = 3, type = "h", xlab = "Year", + main="Number of important discoveries per year") + +# Замест таго, каб пакідаць стандартную сарціроўку (па году), мы можам таксама +# выкарыстаць сарціроўку, каб пабачыць, што для яго характэрна: +sort(discoveries) +# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 +# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 +# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 +# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12 + +stem(discoveries, scale = 2) +# +# Дзесятковая кропка на | +# +# 0 | 000000000 +# 1 | 000000000000 +# 2 | 00000000000000000000000000 +# 3 | 00000000000000000000 +# 4 | 000000000000 +# 5 | 0000000 +# 6 | 000000 +# 7 | 0000 +# 8 | 0 +# 9 | 0 +# 10 | 0 +# 11 | +# 12 | 0 + +max(discoveries) +# 12 +summary(discoveries) +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 0.0 2.0 3.0 3.1 4.0 12.0 + +# Кінуць косць пару разоў +round(runif(7, min = .5, max = 6.5)) +# 1 4 6 1 4 6 4 +# Вашыя нумары будуць адрознівацца ад маіх, хіба што мы не +# ўкажам аднолькавы random.seed(31337) + +# Выцягнуць значэнне з нармальнага размеркавання 9 разоў +rnorm(9) +# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271 +# [7] -0.59975593 0.57629164 1.08455362 + + + +################################################## +# Тыпы даных і базавая арыфметыка +################################################## + +# Цяпер да арыентаванай на праграмавання часткі туторыяла. +# У гэтай секцыі вы пазнаёміцеся з важнымі тыпамі даных у R: +# цэлалікавыя, лічбавыя, сімвальныя, лагічныя і фактары. +# Ёсць і іншыя, але гэтыя - мінімум, які трэба ведаць, каб пачаць. + +# ЦЭЛАЛІКАВЫЯ +# Доўгія цэлалікавыя пішуцца з літарай L +5L # 5 +class(5L) # "integer" +# (Паспрабуйце ?class каб атрымаць больш інфармацыі пра функцыю class().) +# У R кожнае значэнне, як 5L, лічыцца вектарам даўжыні 1 +length(5L) # 1 +# Вы можаце зрабіць цэлалікавы вектар з даўжынёй больш за 1, таксама: +c(4L, 5L, 8L, 3L) # 4 5 8 3 +length(c(4L, 5L, 8L, 3L)) # 4 +class(c(4L, 5L, 8L, 3L)) # "integer" + +# ЛІЧБАВЫЯ +# "numeric" - гэта лічба падвоенай дакладнасці з плаваючай кропкай +5 # 5 +class(5) # "numeric" +# Зноў жа, усё ў R ёсць вектарам; +# вы можаце зрабіць лічбавы вектар з больш чым адным элементам +c(3, 3, 3, 2, 2, 1) # 3 3 3 2 2 1 +# Вы таксама можаце выкарыстоўваць навуковы запіс +5e4 # 50000 +6.02e23 # пастаянная Авагадра +1.6e-35 # Планкаўская даўжыня +# Таксама ёсць бясконца вялікія і маленькія лікі +class(Inf) # "numeric" +class(-Inf) # "numeric" +# Вы можаце выкарыстоўваць "Inf", напрыклад, у integrate(dnorm, 3, Inf); +# пазбаўляе ад неабходнасці ў табліцах нармальнага размеркавання. + +# БАЗАВАЯ АРЫФМЕТЫКА +# Вы можаце рабіць арыфметычныя аперацыі з лічбамі +# Арыфметычныя аперацыі на сумесі цэлалікавых і лічбавых тыпаў даюць лічбавы +10L + 66L # 76 # цэлалікавы плюс цэлалікавы дае цэлалікавы +53.2 - 4 # 49.2 # лічбавы мінус лічбавы дае лічбавы +2.0 * 2L # 4 # лічбавы памножыць на цэлалікавы дае лічбавы +3L / 4 # 0.75 # цэлалікавы падзяліць на лічбавы дае лічбавы +3 %% 2 # 1 # рэшта ад двух лічбавых - таксама лічбавы +# Нядзеючыя арыфметычныя аперацыі даюць "not-a-number": +0 / 0 # NaN +class(NaN) # "numeric" +# Вы можаце рабіць арыфметычныя аперацыі з двума вектарамі з даўжынёй, +# большай за 1, да тых пор, пакуль даўжыня большага вектара +# кратная даўжыні меншага +c(1, 2, 3) + c(1, 2, 3) # 2 4 6 +# Паколькі асобная лічба - гэта вектар даўжыні адзін, скаляры прымяняюцца +# паэлементна да вектара +(4 * c(1, 2, 3) - 2) / 2 # 1 3 5 +# Калі гэта не скаляр, будзьце асцярожнымі праводзячы арыфметычныя аперацыі +# з вектарамі рознай даўжыні. Хаця гэта і магчыма, +c(1, 2, 3, 1, 2, 3) * c(1, 2) # 1 4 3 2 2 6 +# Адпаведныя даўжыні з'яўляюцца лепшай практыкай і палягчаюць чытанне +# у большасці выпадкаў +c(1, 2, 3, 1, 2, 3) * c(1, 2, 1, 2, 1, 2) # 1 4 3 2 2 6 + +# СІМВАЛЬНЫЯ +# У R няма розніцы паміж радкамі і сімваламі +"Horatio" # "Horatio" +class("Horatio") # "character" +class("H") # "character" +# Гэта ўсё сімвальныя вектары даўжыні 1 +# Вось даўжэйшы: +c("alef", "bet", "gimmel", "dalet", "he") +# => "alef" "bet" "gimmel" "dalet" "he" +length(c("Call","me","Ishmael")) # 3 +# Вы можаце прымяняць regex аперацыі на сімвальных вектарах: +substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " +gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis." +# У R ёсць некалькі падрыхтаваных сімвальных вектараў: +letters +# => +# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" +# [20] "t" "u" "v" "w" "x" "y" "z" +month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" + +# ЛАГІЧНЫЯ +# У R лагічным тыпам ёсць "logical" + +class(TRUE) # "logical" +class(FALSE) # "logical" +# Яны паводзяць сябе звычайна +TRUE == TRUE # TRUE +TRUE == FALSE # FALSE +FALSE != FALSE # FALSE +FALSE != TRUE # TRUE +# Адсутныя даныя (NA) таксама лагічнага тыпу +class(NA) # "logical" +# Выкарыстоўвайце | і & для лагічных аперацый. +# АБО +TRUE | FALSE # TRUE +# І +TRUE & FALSE # FALSE +# Выкарыстоўванне | і & на вектарах павяртае паэлементныя лагічныя аперацыі +c(TRUE, FALSE, FALSE) | c(FALSE, TRUE, FALSE) # TRUE TRUE FALSE +c(TRUE, FALSE, TRUE) & c(FALSE, TRUE, TRUE) # FALSE FALSE TRUE +# Вы можаце праверыць, ці x TRUE +isTRUE(TRUE) # TRUE +# Тут мы атрымоўваем лагічны вектар з некалькімі элементамі: +c("Z", "o", "r", "r", "o") == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c("Z", "o", "r", "r", "o") == "Z" # TRUE FALSE FALSE FALSE FALSE + +# ФАКТАРЫ +# Фактар выкарыстоўваецца для катэгарычных даных +# Фактары могуць быць упарадкаванымі (як адзнакі) +# або неўпарадкаванымі (як колеры) +factor(c("blue", "blue", "green", NA, "blue")) +# blue blue green blue +# Levels: blue green +# "levels" - гэта значэнні, якія могуць прыймаць катэгарычныя даныя +# Заўважце, што адсутныя даныя не ўваходзяць ва ўзроўні +levels(factor(c("green", "green", "blue", NA, "blue"))) # "blue" "green" +# Калі вектар фактараў мае даўжыню 1, яго ўзроўні будуць таксама мець даўжыню 1 +length(factor("green")) # 1 +length(levels(factor("green"))) # 1 +# Фактары звычайна можна пабачыць у фрэймах даных, структуры даных, +# з якою мы разбяромся пазней +data(infert) # "Infertility after Spontaneous and Induced Abortion" +levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs" + +# NULL +# "NULL" дзіўны, выкарыстоўвайце яго каб "абнуляць" вектары +class(NULL) # NULL +parakeet = c("beak", "feathers", "wings", "eyes") +parakeet # "beak" "feathers" "wings" "eyes" +parakeet <- NULL +parakeet # NULL + +# ПРЫВЯДЗЕННЕ ДАНЫХ +# Прывядзенне даных - гэта калі вы прымушаеце значэнне прыняць іншы тып +as.character(c(6, 8)) # "6" "8" +as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE +# Калі вы пакладзяце элементы розных тыпаў у вектар, +# адбудзецца дзіўнае прывядзенне: +c(TRUE, 4) # 1 4 +c("dog", TRUE, 4) # "dog" "TRUE" "4" +as.numeric("Bilbo") +# => +# [1] NA +# Warning message: +# NAs introduced by coercion + +# Майце на ўвазе: гэта былі толькі базавыя тыпы даных +# Існуе нашмат болей тыпаў даных, такіх як даты, часавыя рады і іншыя. + + + +################################################## +# Пераменныя, цыклы, if/else +################################################## + +# Пераменныя як скрыні, у якіх захоўваюцца значэнні для пазнейшага выкарыстання. +# Мы называем гэта "прызначэннем" значэння пераменнай. +# Наяўнасць пераменных дае нам магчымасць выкарыстоўваць цыклы, +# функцыі і інструкцыю if/else + +# ПЕРАМЕННЫЯ +# Ёсць шмат спосабаў прызначыць нешта: +x = 5 # гэта магчыма +y <- "1" # гэта традыцыйна прынята +TRUE -> z # гэта працуе, але выглядае дзіўна +# Звярніцеся да Інтэрнэту, каб даведацца пра іх працу і перавагі. + +# ЦЫКЛЫ +# Для цыклаў ёсць +for (i in 1:4) { + print(i) +} +# Ёсць цыклы while +a <- 10 +while (a > 4) { + cat(a, "...", sep = "") + a <- a - 1 +} +# Майце на ўвазе, што цыклы for і while працуюць павольна ў R +# Аперацыі на цэлых вектарах (г.з на цэлых радках, цэлых калонках) +# або функцыі накшталт apply() (абмяркуем гэта пазней) маюць перавагу + +# IF/ELSE +# Зноў жа, усё даволі стандартна +if (4 > 3) { + print("4 болей за 3") +} else { + print("4 не болей за 3") +} +# => +# [1] "4 болей за 3" + +# ФУНКЦЫІ +# Аб'яўляюцца так: +jiggle <- function(x) { + x = x + rnorm(1, sd=.1) # дадаць крыху (кантралюемага) шуму + return(x) +} +# Выклікаюцца як і любыя іншыя функцыі R: +jiggle(5) # 5±ε. Пасля set.seed(2716057), jiggle(5)==5.005043 + + + +########################################################################### +# Структуры даных: вектары, матрыцы, фрэймы даных і масівы +########################################################################### + +# АДНАМЕРНЫЯ + +# Пачнём з самага пачатку, і з нечага, што вы ўжо ведаеце: вектараў. +vec <- c(8, 9, 10, 11) +vec # 8 9 10 11 +# Мы запытваем дакладны элемент, пазначаючы падмноства квадратнымі дужкамі +# (Заўважце, што адлік у R пачынаецца з 1) +vec[1] # 8 +letters[18] # "r" +LETTERS[13] # "M" +month.name[9] # "September" +c(6, 8, 7, 5, 3, 0, 9)[3] # 7 +# Мы таксама можам шукаць індэксы дакладных кампанентаў, +which(vec %% 2 == 0) # 1 3 +# узяць толькі першыя або астатнія некалькі запісаў вектара, +head(vec, 1) # 8 +tail(vec, 2) # 10 11 +# або даведацца, ці ёсць дакладнае значэнне ў вектары +any(vec == 10) # TRUE +# Калі індэкс "пераваліць", вы атрымаеце NA: +vec[6] # NA +# Вы можаце знайсці даўжыню свайго вектара з length() +length(vec) # 4 +# Вы можаце праводзіць аперацыі над цэлымі вектарамі або часткамі вектараў +vec * 4 # 32 36 40 44 +vec[2:3] * 5 # 45 50 +any(vec[2:3] == 8) # FALSE +# і R мае шмат убудаваных функцый для падсумоўвання вектараў +mean(vec) # 9.5 +var(vec) # 1.666667 +sd(vec) # 1.290994 +max(vec) # 11 +min(vec) # 8 +sum(vec) # 38 +# Больш прыемных убудаванак: +5:15 # 5 6 7 8 9 10 11 12 13 14 15 +seq(from = 0, to = 31337, by = 1337) +# => +# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707 +# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751 + +# ДВУМЕРНЫЯ (УСЕ АДНАГО КЛАСУ) + +# Вы можаце зрабіць матрыцу з запісаў аднолькавага тыпу вось так: +mat <- matrix(nrow = 3, ncol = 2, c(1, 2, 3, 4, 5, 6)) +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# У адрозненні ад вектара, класам матрыцы ёсць "matrix", што б у ёй не было +class(mat) # "matrix" "array" +# Запытаць першы радок +mat[1, ] # 1 4 +# Perform operation on the first column +3 * mat[, 1] # 3 6 9 +# Правесці аперацыю над першай калонкай +mat[3, 2] # 6 + +# Транспанаваць усю матрыцу +t(mat) +# => +# [,1] [,2] [,3] +# [1,] 1 2 3 +# [2,] 4 5 6 + +# Памнажэнне матрыц +mat %*% t(mat) +# => +# [,1] [,2] [,3] +# [1,] 17 22 27 +# [2,] 22 29 36 +# [3,] 27 36 45 + +# cbind() склейвае вектары па калонках каб зрабіць матрыцу +mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog")) +mat2 +# => +# [,1] [,2] +# [1,] "1" "dog" +# [2,] "2" "cat" +# [3,] "3" "bird" +# [4,] "4" "dog" +class(mat2) # matrix +# Зноў жа, заўважце, што здарылася! +# Таму што матрыца павінна змяшчаць у сабе запісы аднолькавага тыпу, +# усё павінна быць ператворана ў сімвальны клас +c(class(mat2[, 1]), class(mat2[, 2])) + +# rbind() склейвае вектары па радках каб стварыць матрыцу +mat3 <- rbind(c(1, 2, 4, 5), c(6, 7, 0, 4)) +mat3 +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 2 4 5 +# [2,] 6 7 0 4 +# Ах, усё аднаго класу. Ніякага прывядзення. Нашмат лепей. + +# ДВУМЕРНЫЯ (РОЗНЫХ КЛАСАЎ) + +# Для калонак розных тыпаў выкарыстоўвайце фрэймы даных +# Гэтая структура даных дужа карысная для статыстычнага праграмавання, +# яе версія была дададзена ў Python у пакеце "pandas". + +students <- data.frame(c("Cedric", "Fred", "George", "Cho", "Draco", "Ginny"), + c( 3, 2, 2, 1, 0, -1), + c( "H", "G", "G", "R", "S", "G")) +names(students) <- c("name", "year", "house") # даць імёны калонкам +class(students) # "data.frame" +students +# => +# name year house +# 1 Cedric 3 H +# 2 Fred 2 G +# 3 George 2 G +# 4 Cho 1 R +# 5 Draco 0 S +# 6 Ginny -1 G +class(students$year) # "numeric" +class(students[,3]) # "factor" +# find the dimensions +nrow(students) # 6 +ncol(students) # 3 +dim(students) # 6 3 +# Функцыя data.frame() аўтаматычна ператварала сімвальныя вектары +# ў фактарныя вектары; Гэта змянілася ў R 4.0.0. Калі ваша версія +# R старэйшая, адключыце гэта ўстанавіўшы stringsAsFactors = FALSE +# калі ствараеце data.frame +?data.frame + +# Існуе шмат звілістых спосабаў стварыць падмноства фрэйма даных, +# усе па-свойму розныя +students$year # 3 2 2 1 0 -1 +students[, 2] # 3 2 2 1 0 -1 +students[, "year"] # 3 2 2 1 0 -1 + +# Павялічаная версія структуры data.frame - гэта data.table +# Калі працуеце з вялізнымі або панэльнымі данымі, або маеце патрэбу +# аб'яднаць некалькі набораў даных, data.table можа быць добрым выбарам. +# Вось хуткі тур: +install.packages("data.table") # сцягнуць пакет з CRAN +require(data.table) # загрузіць яго +students <- as.data.table(students) +students # заўважце крыху іншы вывад +# => +# name year house +# 1: Cedric 3 H +# 2: Fred 2 G +# 3: George 2 G +# 4: Cho 1 R +# 5: Draco 0 S +# 6: Ginny -1 G +students[name == "Ginny"] # атрымаць радкі, дзе "Ginny" +# => +# name year house +# 1: Ginny -1 G +students[year == 2] # атрымаць радкі, дзе year == 2 +# => +# name year house +# 1: Fred 2 G +# 2: George 2 G +# data.table дазваляе лёгка аб'яднаць два наборы даных +# давайце зробім іншую data.table каб аб'яднаць яе з students +founders <- data.table(house = c("G" , "H" , "R" , "S"), + founder = c("Godric", "Helga", "Rowena", "Salazar")) +founders +# => +# house founder +# 1: G Godric +# 2: H Helga +# 3: R Rowena +# 4: S Salazar +setkey(students, house) +setkey(founders, house) +students <- founders[students] # аб'яднаць два наборы даных з адпаведнымі "house" +setnames(students, c("house", "houseFounderName", "studentName", "year")) +students[, order(c("name", "year", "house", "houseFounderName")), with = F] +# => +# studentName year house houseFounderName +# 1: Fred 2 G Godric +# 2: George 2 G Godric +# 3: Ginny -1 G Godric +# 4: Cedric 3 H Helga +# 5: Cho 1 R Rowena +# 6: Draco 0 S Salazar + +# data.table робіць падсумоўванне табліц простым +students[, sum(year), by = house] +# => +# house V1 +# 1: G 3 +# 2: H 3 +# 3: R 1 +# 4: S 0 + +# Каб выключыць калонку з data.frame ці data.table, +# прызначце ёй значэнне NULL +students$houseFounderName <- NULL +students +# => +# studentName year house +# 1: Fred 2 G +# 2: George 2 G +# 3: Ginny -1 G +# 4: Cedric 3 H +# 5: Cho 1 R +# 6: Draco 0 S + +# Выключыць радок праз падмноства +# Выкарыстоўваючы data.table: +students[studentName != "Draco"] +# => +# house studentName year +# 1: G Fred 2 +# 2: G George 2 +# 3: G Ginny -1 +# 4: H Cedric 3 +# 5: R Cho 1 +# Выкарыстоўваючы data.frame: +students <- as.data.frame(students) +students[students$house != "G", ] +# => +# house houseFounderName studentName year +# 4 H Helga Cedric 3 +# 5 R Rowena Cho 1 +# 6 S Salazar Draco 0 + +# ШМАТМЕРНЫЯ (УСЕ ЭЛЕМЕНТЫ АДНАГО ТЫПУ) + +# Масівы ствараюць n-мерныя табліцы +# Усе элементы павінны быць аднаго тыпу +# Вы можаце стварыць двухмерную табліцу (нешта накшталт матрыцы) +array(c(c(1, 2, 4, 5), c(8, 9, 3, 6)), dim = c(2, 4)) +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 4 8 3 +# [2,] 2 5 9 6 +# Вы можаце выкарыстоўваць масівы, каб таксама зрабіць трохмерныя матрыцы +array(c(c(c(2, 300, 4), c(8, 9, 0)), c(c(5, 60, 0), c(66, 7, 847))), dim = c(3, 2, 2)) +# => +# , , 1 +# +# [,1] [,2] +# [1,] 2 8 +# [2,] 300 9 +# [3,] 4 0 +# +# , , 2 +# +# [,1] [,2] +# [1,] 5 66 +# [2,] 60 7 +# [3,] 0 847 + +# СПІСЫ(ШМАТМЕРНЫЯ, МАГЧЫМА НЯРОЎНЫЯ, З РОЗНЫХ ТЫПАМІ) + +# Нарэшце, у R ёсць спісы (вектараў) +list1 <- list(time = 1:40) +list1$price = c(rnorm(40, .5*list1$time, 4)) # рандом +list1 +# Вы можаце атрымаць элементы спіса наступным чынам +list1$time # адзін спосаб +list1[["time"]] # іншы спосаб +list1[[1]] # яшчэ іншы спосаб +# => +# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +# [34] 34 35 36 37 38 39 40 +# Вы можаце вылучаць падмноства спісаў як і любых іншых вектараў +list1$price[4] + +# Спісы не найэфектыўнейшая структура даных для працы ў R; +# пакуль у вас няма вельмі добрай прычыны, лепей аддаваць перавагу data.frames +# Спісы звычайна павяртаюцца функцыямі, якія выконваюць лінейныя рэгрэсіі + +################################################## +# Сямейства функцый apply() +################################################## + +# Памятаеце mat? +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Выкарыстоўвайце apply(X, MARGIN, FUN) каб прымяніць функцыю FUN на матрыцы X +# для радкоў (MAR = 1) або калонак (MAR = 2) +# Усё так, R выконвае FUN на кожным радку (або калонцы) X нашмат хутчэй +# за цыклы for і while +apply(mat, MAR = 2, jiggle) +# => +# [,1] [,2] +# [1,] 3 15 +# [2,] 7 19 +# [3,] 11 23 +# іншыя функцыі: ?lapply, ?sapply + +# Не бойцеся, кожны згодны, што гэта даволі заблытана + +# Пакет plyr накіраваны на замену (і паляпшэнне) сямейства *apply(). +install.packages("plyr") +require(plyr) +?plyr + + + +######################### +# Загрузка даных +######################### + +# "pets.csv" - файл з інтэрнэту +# (але гэта таксама можа быць файл на вашым уласным камп'ютары) +require(RCurl) +pets <- read.csv(textConnection(getURL("https://learnxinyminutes.com/pets.csv"))) +pets +head(pets, 2) # першыя два радкі +tail(pets, 1) # апошні радок + +# Каб захаваць фрэйм даных або матрыцу ў .csv файл +write.csv(pets, "pets2.csv") # зрабіць новы .csv файл +# устанаўлівайце працоўную дырэкторыю з setwd(), дазнавайцеся яе з getwd() + +# Глядзіце ?read.csv і ?write.csv каб атрымаць больш інфармацыі + + + +######################### +# Статыстычны Аналіз +######################### + +# Лінейная рэгрэсія! +linearModel <- lm(price ~ time, data = list1) +linearModel # выводзіць рэзультаты рэгрэсіі +# => +# Call: +# lm(formula = price ~ time, data = list1) +# +# Coefficients: +# (Intercept) time +# 0.1453 0.4943 +summary(linearModel) # больш падрабязны вывад з рэгрэсіі +# => +# Call: +# lm(formula = price ~ time, data = list1) +# +# Residuals: +# Min 1Q Median 3Q Max +# -8.3134 -3.0131 -0.3606 2.8016 10.3992 +# +# Coefficients: +# Estimate Std. Error t value Pr(>|t|) +# (Intercept) 0.14527 1.50084 0.097 0.923 +# time 0.49435 0.06379 7.749 2.44e-09 *** +# --- +# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 +# +# Residual standard error: 4.657 on 38 degrees of freedom +# Multiple R-squared: 0.6124, Adjusted R-squared: 0.6022 +# F-statistic: 60.05 on 1 and 38 DF, p-value: 2.44e-09 +coef(linearModel) # выцягнуць чаканыя параметры +# => +# (Intercept) time +# 0.1452662 0.4943490 +summary(linearModel)$coefficients # іншы спосаб выцягнуць рэзультаты +# => +# Estimate Std. Error t value Pr(>|t|) +# (Intercept) 0.1452662 1.50084246 0.09678975 9.234021e-01 +# time 0.4943490 0.06379348 7.74920901 2.440008e-09 +summary(linearModel)$coefficients[, 4] # p-значэнні +# => +# (Intercept) time +# 9.234021e-01 2.440008e-09 + +# АГУЛЬНЫЯ ЛІНЕЙНЫЯ МАДЭЛІ +# Лагістычная рэгрэсія +set.seed(1) +list1$success = rbinom(length(list1$time), 1, .5) # выпадковае бінарнае значэнне +glModel <- glm(success ~ time, data = list1, family=binomial(link="logit")) +glModel # выводзіць рэзультат лагістычнай рэгрэсіі +# => +# Call: glm(formula = success ~ time, +# family = binomial(link = "logit"), data = list1) +# +# Каэфіцыенты: +# (Intercept) time +# 0.17018 -0.01321 +# +# Degrees of Freedom: 39 Total (i.e. Null); 38 Residual +# Null Deviance: 55.35 +# Residual Deviance: 55.12 AIC: 59.12 +summary(glModel) # больш падрабязны вывад з рэгрэсіі +# => +# Call: +# glm( +# formula = success ~ time, +# family = binomial(link = "logit"), +# data = list1) + +# Deviance Residuals: +# Min 1Q Median 3Q Max +# -1.245 -1.118 -1.035 1.202 1.327 +# +# Coefficients: +# Estimate Std. Error z value Pr(>|z|) +# (Intercept) 0.17018 0.64621 0.263 0.792 +# time -0.01321 0.02757 -0.479 0.632 +# +# (Dispersion parameter for binomial family taken to be 1) +# +# Null deviance: 55.352 on 39 degrees of freedom +# Residual deviance: 55.121 on 38 degrees of freedom +# AIC: 59.121 +# +# Number of Fisher Scoring iterations: 3 + + +######################### +# Графікі +######################### + +# УБУДАВАНЫЯ ФУНКЦЫІ ДЛЯ ГРАФІКАЎ +# Кропкавыя дыяграмы! +plot(list1$time, list1$price, main = "fake data") +# Намаляваць лінію рэгрэсіі на існуючай дыяграме +abline(linearModel, col = "red") +# Трымайце шэраг прыемных дыягностык +plot(linearModel) +# Гістаграмы! +hist(rpois(n = 10000, lambda = 5), col = "thistle") +# Слупкаватыя дыяграмы! +barplot(c(1, 4, 5, 1, 2), names.arg = c("red", "blue", "purple", "green", "yellow")) + +# GGPLOT2 +# І гэта нават не найпрыгажэйшыя з графікаў R +# Паспрабуйце пакет ggplot2, у якім больш лепшых графікаў +install.packages("ggplot2") +require(ggplot2) +?ggplot2 +pp <- ggplot(students, aes(x = house)) +pp + geom_bar() +ll <- as.data.table(list1) +pp <- ggplot(ll, aes(x = time, price)) +pp + geom_point() +# ggplot2 has excellent documentation (available http://docs.ggplot2.org/current/) +``` + +## Дзе ўзяць R? + +* Сцягніце R і R GUI з [http://www.r-project.org/](http://www.r-project.org/) +* [RStudio](http://www.rstudio.com/ide/) іншы GUI