בפרקים הקודמים כבר נגענו בפקודות שונות, וקצת בתכנות ב-R, אך בפרק הזה נציג את יסודות התכנות ב-R באופן מסודר.
כשמעלים את RStudio, אז מופיע בצד התחתון שלו ה-Console. בחלק זה ניתן להריץ קוד כמו “מחשבון”. לדוגמה:
cos(2*pi)
## [1] 1
log(10^5)
## [1] 11.51293
log10(10^5)
## [1] 5
sqrt(144)
## [1] 12
12^2
## [1] 144
ניתן ליצור אובייקטים חדשים עם אופרטור ההשמה ->, באופן הבא:
foo <- "bar"
foo
## [1] "bar"
bar <- 99*111
bar
## [1] 10989
שמות משתנים חייבים להתחיל באות (גדולה או קטנה), ויכולים להכיל אותיות, מספרים, קו תחתון _ ונקודה.. כדי לבנות משתנים ששמם הוא בעל משמעות, לעיתים תידרש יותר ממילה אחת, לשם כך מומלץ להפריד עם _.
R הוא רגיש לאותיות קטנות וגדולות (case sensitive), בדרך כלל מקובל להשתמש באותיות קטנות בלבד.
הרצות לדוגמה (מה-console, לכן מופיע התו “<” בתחילת שורה. כדי להריץ את הקוד השמיטו תו זה.
> short_name <- 3
> long_description <- "This is a description of foo bar"
> r_is_great <- 10
> r_is_great
> r_is_great
[1] 10
> R_is_great
Error: object 'R_is_great' not found
ל-R יש פונקציות מובנות, ופונקציות הנמצאות בתוך חבילות. קריאה לפונקציה מתבצעת באופן הבא:
function_name(arg1 = val1, arg2 = val2, ...)
אם הפונקציה אינה ב-Base R אז ראשית צריך לטעון את החבילה באחד משני האופנים הבאים:
# either do this
package_name::function_name(...)
# or first load, then use freely
library(package_name)
function_name(...)
library(tidyvers)
glimpse(iris)
ggplot(data = iris) +
geom_point(aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
+ geom_smooth(method = "lm")
fliter(iris, Species = "setosa")
ב-Cheat sheet הבא מפורטים שלושה סוגים של תחבירים (syntax.pdf): https://github.com/rstudio/cheatsheets/raw/master/syntax.pdf
במהלך הקורס ניתן דגש לתחביר Tidyverse, אך מומלץ להכיר גם את התחבירים האחרים. לדוגמה, חישוב ממוצע בתחביר הבסיסי ובתחביר Tidyverse יראה כך:
# base R syntax:
# calculate average
mean(mtcars$mpg)
## [1] 20.09062
# average vs. discrete var
mean(mtcars$mpg[mtcars$cyl==4])
## [1] 26.66364
mean(mtcars$mpg[mtcars$cyl==6])
## [1] 19.74286
mean(mtcars$mpg[mtcars$cyl==8])
## [1] 15.1
# plot histogram
hist(mtcars$disp)
# subsetting
mtcars[mtcars$mpg > 30,]
## mpg cyl disp hp drat wt qsec vs am gear carb
## Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
## Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
## Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
# Tidyverse syntax
library(tidyverse)
# calculate average
mtcars %>%
summarize(mean(mpg))
## mean(mpg)
## 1 20.09062
# average vs. discrete var
mtcars %>%
group_by(cyl) %>%
summarize(mean(mpg))
## # A tibble: 3 x 2
## cyl `mean(mpg)`
## <dbl> <dbl>
## 1 4 26.7
## 2 6 19.7
## 3 8 15.1
# plot histogram
ggplot(mtcars, aes(x=disp)) + geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# subsetting
mtcars %>% filter(mpg > 30)
## mpg cyl disp hp drat wt qsec vs am gear carb
## 1 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
## 2 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
## 3 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
## 4 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
משתנה ב-R יכול לקבל ערכים ממספר סוגים, העיקריים שבהם:
שימו לב שהשמה נראית כחץ -> (בעדיפות) או כשיוויון =
לדוגמה:
integer_example <- 10
integer_example
## [1] 10
numeric_example <- pi # pi is a reserved word...
numeric_example
## [1] 3.141593
character_examples <- "hello world"
character_examples
## [1] "hello world"
date_example <- as.Date("2018-10-01")
date_example
## [1] "2018-10-01"
factor_example <- as.factor(c("big", "big", "small", "medium", "small", "big", "bigger"))
factor_example
## [1] big big small medium small big bigger
## Levels: big bigger medium small
summary(factor_example)
## big bigger medium small
## 3 1 1 2
logical_example <- c(TRUE, TRUE, FALSE, TRUE)
logical_example
## [1] TRUE TRUE FALSE TRUE
בעצם כל האובייקים ב-R הם מערכים (גם אם יש בהם רק ערך אחד, הם עדיין מערכים ולא סקלר). דוגמאות:
tibble אך נדון בו בפרק הבא.int_vector <- 1:10
int_vector
## [1] 1 2 3 4 5 6 7 8 9 10
dbl_vector <- c(1, pi, 3.3, sqrt(2)/2)
dbl_vector
## [1] 1.0000000 3.1415927 3.3000000 0.7071068
chr_vector <- c("hello", "world", 1, pi) # see that the numbers are type cast-ed into characters
chr_vector
## [1] "hello" "world" "1"
## [4] "3.14159265358979"
cbind(1:10, 21:30, 41:50)
## [,1] [,2] [,3]
## [1,] 1 21 41
## [2,] 2 22 42
## [3,] 3 23 43
## [4,] 4 24 44
## [5,] 5 25 45
## [6,] 6 26 46
## [7,] 7 27 47
## [8,] 8 28 48
## [9,] 9 29 49
## [10,] 10 30 50
# the following is a data frame:
df_example <- data.frame(city = c("Jerusalem", "Tel-Aviv", "Haifa", "Rishon LeTzion"),
order_population = c(1, 2, 3, 4))
df_example
## city order_population
## 1 Jerusalem 1
## 2 Tel-Aviv 2
## 3 Haifa 3
## 4 Rishon LeTzion 4
# another example
mtcars
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
## Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
## Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
## Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
## Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
## Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
## Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
## Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
## Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
## Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
# a list can contain any combination of arrays, data frames, and lists
list(int_vector, dbl_vector, chr_vector, df_example)
## [[1]]
## [1] 1 2 3 4 5 6 7 8 9 10
##
## [[2]]
## [1] 1.0000000 3.1415927 3.3000000 0.7071068
##
## [[3]]
## [1] "hello" "world" "1"
## [4] "3.14159265358979"
##
## [[4]]
## city order_population
## 1 Jerusalem 1
## 2 Tel-Aviv 2
## 3 Haifa 3
## 4 Rishon LeTzion 4
כדי לפנות לאיבר מסוים בתוך וקטור משתמשים בסוגריים מרובעים [], לדוגמה
dbl_vector[1:3]
## [1] 1.000000 3.141593 3.300000
פעולות אריתמטיות עובדות על משתנים ומערכים כל עוד גודלם תואם (והסוג שלהם מאפשר פעולות אלו)
c(1, pi, 3.3, sqrt(2)/2)^2
## [1] 1.000000 9.869604 10.890000 0.500000
#c("hello", "world", 1, pi) + 1 # yields an error - you can't add 1 to a character
> c("hello", "world", 1, pi) + 1
Error in c("hello", "world", 1, pi) + 1 :
non-numeric argument to binary operator
בדרך כלל, מומלץ להימנע ככל שניתן מלולאות. חלק גדול מהפעולות ב-R פועלות באופן וקטורי או מטריציוני. לולאת for בנוייה מהתבנית הבאה:
for (i in vector){
# the action that needs to be done...
}
שימוש בלולאות לעומת פעולות וקטוריות.
seq. כדי ללמוד על הפונקציה הקש ב-console:?seq
seq?forSys.time כדי למדוד את משך הזמן שנדרש לשתי הפעולות|&!xor(a,b)==!=5 == 6
## [1] FALSE
6 == 6
## [1] TRUE
5 == 6 | 6 == 6
## [1] TRUE
Inf > 10^10
## [1] TRUE
TRUE & FALSE
## [1] FALSE
xor(TRUE, FALSE)
## [1] TRUE
FALSE == !TRUE
## [1] TRUE
FALSE != TRUE
## [1] TRUE
near עובדת?x <- sqrt(2)^2
x == 2
## [1] FALSE
dplyr::near(sqrt(2)^2, 2)
## [1] TRUE
בסטטיסטיקה, לעיתים קרובות ישנם “ערכים חסרים”, תצפיות שלא נמדדו או לא תועדו. ב-R, ערכים אלו מיוצגים על ידי NA.
NANA+0
NA*1
NA^0
NA | TRUE
NA & FALSE
NA*0
if (condition){
expression
} else if (condition){
expression
} else {
expression
}
בשלבים הראשוניים של עבודה עם R מומלץ להיעזר ב-Cheat sheet של “base-r.pdf” בקישור: http://github.com/rstudio/cheatsheets/raw/master/base-r.pdf
מעבר לפקודות הבסיסיות שנקראות “Base R”, ישנן חבילות רבות שמעשירות את R. מה שהופך את R לשפה מאוד אטרקטיבית משום שלהרבה מהצרכים שבהם אתם עשויים להיתקל, כבר פותחו פתרונות.
בפרק הבא נעמיק בחבילות חשובות המשמשות לעיבוד נתונים ברמה הבסיסית (סינונים, טרנספורמציות, וכו’)