הקדמה

בשיעור הזה נתמקד בעבודה עם טבלאות נתונים - data frame. רוב העבודה שלכם מול R תהיה בעזרת טבלאות נתונים המניחים מבנה מסוים לנתונים שאותם מנתחים. בשיעור הזה נלמד איך לעבוד עם טבלאות בשפת הבסיס של R אבל בשיעורים הבאים נעשה שימוש בספריות חיצוניות כגון dplyr ו sqldf המקלות מאוד על עבודה עם טבלאות נתונים.


מטרות

עד סוף השיעור תדעו:

  • איך לגשת לטבלאות נתונים
  • איך לבצע שאילתות על טבלאות הנתונים
  • לבצע את כל הדברים שאתם רגילים לעשות בעולם ה Relational Database

מבנה ה data.frame ב R

הרעיון מאחורי טבלת נתונים היא שכל שורה בטלה מייצגת תצפית ברמת ניתוח מסוימת, ועמודות הטבלה מכילים מאפיינים שונים עבור אותה תצפית. הרעיון של טבלת נתונים מיושם ב R בעזרת אובייקט ה data.frame שניתן לחשוב עליה ולגשת עליה בכמה אופנים:

  • טבלה כמטריצה – ולכן ניתן לגשת עליה כאילו הייתה מטריצה
  • טבלה כאוסף של וקטורים – data.frame היא מקרה פרטי של רשימה (list) המאגדת יחד וקטורים מסוגים שונים. ולכן, כל פעולה שעשינו על וקטורים ניתן לעשות לעמודות של data.frame

גישה ל data.frame

כאמור, בכל סוגי המבנים ניתן לגשת לנתונים באחד מ 3 דרכים:

  • בחירת נתונים לפי מקום
  • בחירת נתונים לפי תנאי (ערך לוגי)
  • בחירת נתונים לפי שם

בהמשך השיעור נתן דוגמאות על טבלת iris המובנית בתוך R

קודם בא נשמור גרסא מקומית של אותו טבלה שעליה נוכל להדגים:

irisdata <- iris

גישה לנתונים לפי מיקום

כאמור, טבלה היא סוג של מטריצה, וכל הכללים שלמדנו בשיעור הקודם על גישה לנותנים במטריצות חלים גם כאן.

  • ניתן לגשת לנתונים בטבלה בצורה הבאה:
TableName[Row Index, Coloumn Index]

לדוגמא:

# Rows 1 to 5; Coloumns 1,3,4
irisdata[1:5, c(1,3,4)]
Sepal.Length Petal.Length Petal.Width
5.1 1.4 0.2
4.9 1.4 0.2
4.7 1.3 0.2
4.6 1.5 0.2
5.0 1.4 0.2
  • החלפת נתונים במיקום ספציפי באותה צורה כמו במטריצות:

לדוגמא:

irisdata[1:2, 2:3] <- NA

irisdata[1:5, c(1,2,3)]
Sepal.Length Sepal.Width Petal.Length
5.1 NA NA
4.9 NA NA
4.7 3.2 1.3
4.6 3.1 1.5
5.0 3.6 1.4

גישה לנתונים לפי תנאי

כמו בוקטורים ומטריצות ניתן לבחור לפי תנאי. בדרך כלל נרצה לשים תנאי על עמודה מסוימת, על זה נלמד בהמשך השיעור. אבל אחד הפעולות הנפוצות לבצע על תנאי על טבלה שלמה היא לטיפול בערכים חסרים או להחליף ערך מסוים הנמצא בכל הטבלה. הפקודה is.na מחזיר ערך לוגי לכל ערך בווקטור, TRUE עם הערך חסר ו FALSE עם הערך לא חסר.

# Replace Missing data with default value
irisdata[is.na(irisdata)] <- 9999

irisdata[1:5, c(1,2,3)]
Sepal.Length Sepal.Width Petal.Length
5.1 9999.0 9999.0
4.9 9999.0 9999.0
4.7 3.2 1.3
4.6 3.1 1.5
5.0 3.6 1.4

גישה לנתונים לפי שם

גם במטריצות ווקטורים ניתן לתת שמות לעמודות ולשורות, עם זאת האובייקט הנפוץ ביותר לשימוש בשמות הוא טבלה data.frame המקשר בין וקטורים שונים.

ה syntax לשלוף נתון מתוך טבלה היא:

TableName$ColumnName[RowNumber]
  • השמטת החלק של השורה תחזיר את כל העמודה.

לדוגמא:

# Show the first 5 values
irisdata$Sepal.Length[1:5]
## [1] 5.1 4.9 4.7 4.6 5.0
# We can use a coloumn directly like any other vector

hist(irisdata$Sepal.Length)



שאילתות על טבלאות

כמו בכל דבר ב R , הכוח האמיתי בא כשמשלבים בין השיטות השונות של גישה לטבלאות. כלומר גם גישה לטבלה עם שמות עמודות וגם כמטריצה לפי מקום ותנאים.

עכשיו שהבנו את העקרונות של גישה לטבלאות בוא נראה איך אפשר לשלב ביניהם לבצע שאילתות על הטבלה.


שאילתות בסיסיות

לבחירת שאילתא על טבלה, מכניסים את התנאי למקום הראשון ואת העמודה שרוצים בחזרה במקום השני.

  • הסינטקס הבסיסי לשאילתא היא:
Table[Condition, Columns]
  • ניתן לבחור את העמודה הרצויה לפי מקום, לדוגמא:
# One Coloumn
irisdata[irisdata$Sepal.Length>7.6,1]
## [1] 7.7 7.7 7.7 7.9 7.7
  • או לבחור טווח של עמודות רציפות בעזרת הפעולה :
# Consecutive Coloumns
irisdata[irisdata$Sepal.Length>7.6,1:3]
Sepal.Length Sepal.Width Petal.Length
118 7.7 3.8 6.7
119 7.7 2.6 6.9
123 7.7 2.8 6.7
132 7.9 3.8 6.4
136 7.7 3.0 6.1
  • אם רוצים עמודות ספציפיות מאגדים אותם בעזרת האופרטור c
# Specific Coloumns
irisdata[irisdata$Sepal.Length>7.6,c(1,3,5)]
Sepal.Length Petal.Length Species
118 7.7 6.7 virginica
119 7.7 6.9 virginica
123 7.7 6.7 virginica
132 7.9 6.4 virginica
136 7.7 6.1 virginica
  • וגם ניתן לבחור את העמודות הרצויות לפי שם, לדוגמא:
# One Coloumn
## Option 1
irisdata[irisdata$Sepal.Length>7.6,"Sepal.Length"]
## [1] 7.7 7.7 7.7 7.9 7.7
## Option 2
irisdata$Sepal.Length[irisdata$Sepal.Length>7.6]
## [1] 7.7 7.7 7.7 7.9 7.7
# Multiple Coloumns
irisdata[irisdata$Sepal.Length>7.6,c("Species", "Sepal.Length","Sepal.Width")]
Species Sepal.Length Sepal.Width
118 virginica 7.7 3.8
119 virginica 7.7 2.6
123 virginica 7.7 2.8
132 virginica 7.9 3.8
136 virginica 7.7 3.0
  • אם רוצים את כל עמודות הטבלה אז משאירים את המקום השני ריק (אבל חייבים פסיק):
irisdata[irisdata$Sepal.Length>7.6,]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
118 7.7 3.8 6.7 2.2 virginica
119 7.7 2.6 6.9 2.3 virginica
123 7.7 2.8 6.7 2.0 virginica
132 7.9 3.8 6.4 2.0 virginica
136 7.7 3.0 6.1 2.3 virginica

החלפת ערכים בעמודה מסוימת כשהשורה עומדת בתנאי מסוים נעשית באותו שיטה.

# Replace
irisdata[irisdata$Sepal.Length>7.6,c("Sepal.Length","Sepal.Width")] <- 9999

# Show
irisdata[irisdata$Sepal.Length>7.6,]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
118 9999 9999 6.7 2.2 virginica
119 9999 9999 6.9 2.3 virginica
123 9999 9999 6.7 2.0 virginica
132 9999 9999 6.4 2.0 virginica
136 9999 9999 6.1 2.3 virginica

פקודת subset

כיוון ששאילתא בסיסית היא פעולה נפוצה , קיימת ב R פונקציה בשם subset, המקלה על כתיבת השאילתא:

מבנה הפקודה היא:

subset(TableName, Condition, Coloumns)

למשל:

subset(irisdata, Sepal.Width==9999, c("Sepal.Length","Sepal.Width"))
Sepal.Length Sepal.Width
1 5.1 9999
2 4.9 9999
118 9999.0 9999
119 9999.0 9999
123 9999.0 9999
132 9999.0 9999
136 9999.0 9999

בתוך ה c בבחירת העמודות לא חייבים את הגרשיים אבל זה מקרה יוצא דופן


שאילתות אגרגטיביות

פעולה נפוצה מאוד בניתוח נתונים היא לבצע סטטיסטיקות שונות לפי רמות של משתנה מסוים.

הדרך לעשות זאת ב R היא להשתמש באחד הפקודות הבאות המובדלים באובייקט שהן מחזירות ובהתאם במספר הפונקציות שהן יכולות לבצע במקביל.


פקודה כללית tapply

פקודה ממשפחת ה apply שמבצעות איזשהו פעולה על כל ערך ברשימה. שתי הפקודות הבאות בנויות על פקודה זו. בהמשך הקורס נבין בדיוק איך הפקודה הזו עובדת.

  • הפקודה מבצעת חישוב כלשהו לפי רמות של משתנה, ומחזירה וקטור.
  • בפקודה ניתן לבצע מספר סטטיסטיקות או פונקציה כללית על משתנה המטרה.
  • הסינטקס הבסיסית של הפקודה היא:
tapply(Table$Coloumn, Table$GroupColoumn, Computation)

פקודת by

  • הפקודה מבצעת חישוב כלשהו לפי רמות של משתנה, ומחזירה מערך list.
  • בפקודה ניתן לבצע מספר סטטיסטיקות או פונקציה כללית על משתנה המטרה.
  • הסינטקס הבסיסית של הפקודה היא:
by(Table$Coloumn, Table$GroupColoumn, Computation)

פקודת aggregate

  • הפקודה מבצעת חישוב כלשהו לפי רמות של משתנה, ומחזירה טבלה.
  • בפקודה ניתן לבצע סטטיסטיקה אחת על משתנה המטרה.
  • ניתן לבצע על מספר משתני מטרה, ועל צירוף של מספר משתני קבוצה.
  • הסינטקס הבסיסית של הפקודה היא:
aggregate(Table$Coloumn, Table$GroupColoumn, Computation)

# Or

aggregate(Coloumn ~ GroupColoumn, data = Table, Computation)
  • הסינטקס עבור מספר משתני מטרה:
aggregate(cbind(Table$Col1,Table$Col2), Table$GroupColoumn, Computation)

# Or

aggregate(cbind(Col1,Col2) ~ GroupColoumn, data = Table, Computation)
  • הסינטקס עבור מספר משתני קבוצה היא:
aggregate(Table$Coloumn, list(Table$Group1,Table$Group2), Computation)

# Or

aggregate(Coloumn ~ Group1 + Group2, data = Table, Computation)

לרוב נשתמש בפקודה aggregate כי היא נוחה יותר בעבודה עם טבלאות.

הסינטקס של aggregate הוא בסגנון נוסחא של R ועוד נתקל בה בהמשך


בדוגמא הבאה נבצע את אותו חישובים לפי כל אחד מהפונקציות הללו:

tapply(irisdata$Sepal.Length, irisdata$Species, summary)
## $setosa
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.300   4.800   5.000   5.006   5.200   5.800 
## 
## $versicolor
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.900   5.600   5.900   5.936   6.300   7.000 
## 
## $virginica
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##    4.900    6.225    6.500 1006.000    6.900 9999.000
by(irisdata$Sepal.Length, irisdata$Species, summary)
## irisdata$Species: setosa
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.300   4.800   5.000   5.006   5.200   5.800 
## -------------------------------------------------------- 
## irisdata$Species: versicolor
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.900   5.600   5.900   5.936   6.300   7.000 
## -------------------------------------------------------- 
## irisdata$Species: virginica
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##    4.900    6.225    6.500 1006.000    6.900 9999.000
aggregate(Sepal.Length ~ Species, data = irisdata, mean)
Species Sepal.Length
setosa 5.006
versicolor 5.936
virginica 1005.714

שינויים במבנה טבלה

השינויים הבסיסיים שנרצה לבצע על טבלה הינם:

  • הוספת ומחיקת עמודות
  • שינוי שמות עמודות

הוספת עמודה לטבלה

אפשר להוסיף עוד עמודה או דרך חישוב ישיר או על ידי הוספת וקטור בתור עוד עמודה בטבלה.


הוספת עמודה בצורה ישירה

ניתן להוסיף עמודה בצורה ישירה לפי הסינטקס הבא:

Table$Column <- Value

לדוגמא:

# Add a constant value of 5
irisdata$NewCol <- 5
head(irisdata)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewCol
5.1 9999.0 9999.0 0.2 setosa 5
4.9 9999.0 9999.0 0.2 setosa 5
4.7 3.2 1.3 0.2 setosa 5
4.6 3.1 1.5 0.2 setosa 5
5.0 3.6 1.4 0.2 setosa 5
5.4 3.9 1.7 0.4 setosa 5
  • חישוב עמודה חדשה על בסיס עמודה קיימת תעשה באותה צורה.

לדוגמא לחשב את היחס בין אורך עלה לבין הרוחב שלו:

irisdata$NewCol <- irisdata$Sepal.Length/irisdata$Sepal.Width
head(irisdata)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewCol
5.1 9999.0 9999.0 0.2 setosa 0.0005101
4.9 9999.0 9999.0 0.2 setosa 0.0004900
4.7 3.2 1.3 0.2 setosa 1.4687500
4.6 3.1 1.5 0.2 setosa 1.4838710
5.0 3.6 1.4 0.2 setosa 1.3888889
5.4 3.9 1.7 0.4 setosa 1.3846154

הוספת וקטור קיים

לחלופין ניתן לאגד בין טבלה קיימת לוקטור קיים בעל אותו אורך בעזרת פקודת cbind

הסינטקס הבסיסי של הפקודה נתונה על ידי:

cbind(Table1, Table2)

לדוגמא:

# Make a vector
NewCol2 <- 1:150

# Bind the table
irisdata <- cbind(irisdata, NewCol2)
head(irisdata)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewCol NewCol2
5.1 9999.0 9999.0 0.2 setosa 0.0005101 1
4.9 9999.0 9999.0 0.2 setosa 0.0004900 2
4.7 3.2 1.3 0.2 setosa 1.4687500 3
4.6 3.1 1.5 0.2 setosa 1.4838710 4
5.0 3.6 1.4 0.2 setosa 1.3888889 5
5.4 3.9 1.7 0.4 setosa 1.3846154 6

מחיקת עמודה מטבלה

מחיקת עמודה נעשית בצורה ישירה על ידי השמת הערך NULL במקום העמודה בצורה הבאה:

Table$Column <- NULL

לדוגמא:

irisdata$NewCol <- NULL
str(irisdata)
## 'data.frame':    150 obs. of  6 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  9999 9999 3.2 3.1 3.6 ...
##  $ Petal.Length: num  9999 9999 1.3 1.5 1.4 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ NewCol2     : int  1 2 3 4 5 6 7 8 9 10 ...

שימו לב: השמת הערך NA במקום הערך NULL תחליף את תכולת העמודה בערך חסר


שינוי שמות עמודות

שינויים בשמות עמודות תעשה בעזרת הפקודה names.

  • קריאה ישירה לפקודה names תחזיר לנו וקטור עם שמות העמודות לפי סדר הופעתן בטבלה בצורה הבאה:
names(TableName)
  • החלפת שמות כל העמודות בטבלה:
names(TableName) <- c("Name1","Name2",...)
  • ניתן להחליף שם של עמודה מסוימת לפי הסינטקס הבא:
names(TableName)[Column Index] <- "New Name"
  • או של מספר עמודות ספיציפיות לפי המיקום שלהם:
names(TableName)[c(Column Indices)] <- c("Name1","Name2",...)

לדוגמא:

# Save the Names of the Coloumns
originalNames <- names(irisdata)
originalNames
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
## [5] "Species"      "NewCol2"
# Rename Coloumns 1 and 3
names(irisdata)[c(1,3)] <- c("Var1", "Var3")
names(irisdata)
## [1] "Var1"        "Sepal.Width" "Var3"        "Petal.Width" "Species"    
## [6] "NewCol2"
# Rename Coloumn 4
names(irisdata)[4] <- "Col4"
names(irisdata)
## [1] "Var1"        "Sepal.Width" "Var3"        "Col4"        "Species"    
## [6] "NewCol2"
# Rename All Coloumns back to original
names(irisdata) <- originalNames
names(irisdata)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
## [5] "Species"      "NewCol2"

מיון טבלה

ב R ניתן למיין את הטבלה בעזרת הפקודה order וגישה לטבלה כפי שניגשנו למטריצות.

  • הסניטקס הבסיסי תהיה בצורה הבאה:
TableName[order(TableName$Coloumn),]
  • אם נרצה למיין לפי שתי עמודות או יותר נעשה את זה בצורה הבאה:
TableName[order(TableName$Coloumn1,TableName$Coloumn2),]
  • אם רוצים למיין לפי סדר יורד באחד המשתנים אז מוסיפים את הסימן - לפני שם המשתנה, לדוגמא:
TableName[order(TableName$Coloumn1, -TableName$Coloumn2),]

לדוגמא:

irisdata <- irisdata[order(irisdata$Sepal.Length, -irisdata$Sepal.Width),]
head(irisdata)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewCol2
14 4.3 3.0 1.1 0.1 setosa 14
43 4.4 3.2 1.3 0.2 setosa 43
39 4.4 3.0 1.3 0.2 setosa 39
9 4.4 2.9 1.4 0.2 setosa 9
42 4.5 2.3 1.3 0.3 setosa 42
23 4.6 3.6 1.0 0.2 setosa 23

פעולות על מספר טבלאות

ישנם שתי פעולות עיקריות שנרצה לבצע עבור מספר טבלאות. איחוד טבלאות (union) , וסוגים שונים של חיבור בין טבלאות (join)


איחוד בין טבלאות

ניתן לאחד בין טבלאות בעזרת הפקודה הפשוטה rbind שהיא בעצם ביצוע union בין שתי טבלאות או יותר. הסינטקס הבסיסי של הפקודה נתונה על ידי:

rbind(Table1, Table2)

לדגמא:

irisdata2 <- rbind(irisdata, irisdata)

# Return the dimensions of the tables
dim(irisdata)
## [1] 150   6
dim(irisdata2)
## [1] 300   6

חיבור בין טבלאות

חיבור בין טבלאות היא בליבה של עולם הטבלאות הרלציוני, ומהותה היא איחוד בין טבלאות שונות בעזרת מפתח משותף. בשפת ה SQL הפעולה מתבצעת בעזרת פעולות Join למיניהם.

בשפה הבסיסית של R ניתן לבצע את פעולת האיחוד בעזרת הפקודה merge לפי הסינטקס הבא:

merge(Table A, Table B,
      by.x ="KeyTableA" , by.y ="KeyTableB" ,
      all.x = TRUE/FALSE, all.y =TRUE/FALSE )

זאת כאשר הפרמטרים all.x ו all.y קובעות לנו את סוג החיבור בין הטבלאות. להלן טבלה המקשרת בין האפשרויות השונות לבין פעולת ה join בשפת ה SQL:

בשביל להדגים, קודם:

  • ניצור טבלה המחשבת את הממוצע של Sepal.Length לפי העמודה Species
  • ונשנה את שם העמודה המחושבת ל MeanLength
  • ונחליף את הערך setosa בעמודת המפתח Species בערך NA
# Calculate aggregated table
irisMean <- aggregate(Sepal.Length ~ Species, data = irisdata, mean)

# Rename the Calculated Coloumn
names(irisMean)[2] <- "MeanLength"

# Replace setosa with NA
irisMean$Species[irisMean$Species=="setosa"] <- NA
  • עכשיו נדגים חיבור לערכי הבטלה הראשונה (left join) בין 2 הטבלאות לפי המפתח Species
# Do a left join
irisdata <- merge(irisdata, irisMean,
                   by.x = "Species", by.y = "Species",
                   all.x = TRUE,
                   all.y = FALSE)

irisdata[48:53,]
Species Sepal.Length Sepal.Width Petal.Length Petal.Width NewCol2 MeanLength
48 setosa 5.4 3.4 1.7 0.2 21 NA
49 setosa 5.7 3.8 1.7 0.3 19 NA
50 setosa 5.7 4.4 1.5 0.4 16 NA
51 versicolor 5.9 3.0 4.2 1.5 62 5.936
52 versicolor 5.2 2.7 3.9 1.4 60 5.936
53 versicolor 6.0 2.9 4.5 1.5 79 5.936

תרגיל

בתרגיל הבא תעשו שימוש במה שלמדתם ותעזרו בפקודות הבאות על מנת לענות על השאלות:

  • summary : פקודה המחזירה סטטיסטיקה בסיסית על טבלה או וקטור
  • table : פקודה גנרית המחזירה טבלת התפלגות של וקטור על וקטור (ספירה של עמודה אחת מול השניה)
  • prop.table : מקבל אובייקט שנוצר מפקודת table. ומקבל עוד פרמטר מספר 1 עד 3 לפיו מחזיר את שיעור הערכים לפי שורה (1) , עמודה (2), או סך הכל
  • levels : מחזיר את הקטגוריות היחודיות עבור משתנה מסוג factor
  • mean : חישוב ממוצע של וקטור / עמודה
  • plot : פקודה גנרית המייצרת גרף בהתאם לאובייקטים המעוברים עליה
  • ls : מחזיר רשימה של שמות האובייקטים הקיימים בסביבה מסוימת
  • rm : מחיקת משתנה

וכל פקודה אחרת שתשיג את המטרה…

העזרו ב help אם אתם לא יודעים איך להשתמש בפקודה מסוימת

Questions

  1. קראו את הנתונים מ iris לתוך אובייקט בשם iris_data. התבוננו במבנה הנתונים שיצרתם. מה הרמות הייחודיות של העמודה Species?
  2. מה הערך הממוצע של המשתנה Sepal.Length ?
  3. לאיזה סוג פרחים Species יש ערך Sepal.Length גדול מ 5 ?
  4. יצרו גרף של Sepal.Length מול Sepal.Width
  5. יצרו משתנה Grp_Length שמבקל את הערך 1 עבור Sepal.Length גדול מ 5 ו 0 אחרת. בדקו את עצמכם בעזרת הפקודה aggregate
  6. הציגו טבלת התפלגות בין המשתנים Grp_Length ו Species ושמרו את התוצאה באוביקט בשם sumTable
  7. השתמשו בפקודה prop.table על האובייקט sumTable לחשב, פעם אחת את האחוזים לפי שורות, פעם אחת את האחוזים לפי עמודות, ופעם אחת את האחוזים בטבלה
  8. החליפו את הערך של Sepal.Length לערך חסר במקרים בהן Grp_Length שווה ל 0. חישבו ממוצע על המשתנה החדש
  9. מחקו את העמודה Grp_Length
  10. נסו לחבר את מערך המספרים מ 1 עד 5 למערך המספרים 1 עד 2. מה R עושה במקרה כזה?
  11. השתמשו בפקודה ls על מנת לקבל את שמות המשתנים הקיימים. תנקו את אזור העבודה שלכם מנתונים.

Answers

iris_data <- iris

str(iris_data)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
levels(iris_data$Species)
## [1] "setosa"     "versicolor" "virginica"
summary(iris_data)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199 NA
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800 NA
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500 NA
# This does not give the expected result!!
# And worse - Doesnt throw an Error!!
table(iris_data["Sepal.Length">5,"Species"])
setosa versicolor virginica
50 50 50
# Option 1
table(iris_data[iris_data$Sepal.Length>5,"Species"])
setosa versicolor virginica
22 47 49
# Option 2
table(subset(iris_data, Sepal.Length>5, c("Species")))
setosa versicolor virginica
22 47 49
plot(iris_data$Sepal.Length, iris_data$Sepal.Width)

iris_data$Grp_Length <- 0
iris_data$Grp_Length[iris_data$Sepal.Length>=5] <- 1

# Lets look at a summary to make sure we are right

aggregate(Sepal.Length ~ Grp_Length, data =iris_data, max)
Grp_Length Sepal.Length
0 4.9
1 7.9
sumTable <- table(iris_data$Species, iris_data$Grp_Length)
prop.table(sumTable,1)
/ 0 1
setosa 0.40 0.60
versicolor 0.02 0.98
virginica 0.02 0.98
prop.table(sumTable,2)
/ 0 1
setosa 0.9090909 0.2343750
versicolor 0.0454545 0.3828125
virginica 0.0454545 0.3828125
prop.table(sumTable)
/ 0 1
setosa 0.1333333 0.2000000
versicolor 0.0066667 0.3266667
virginica 0.0066667 0.3266667
iris_data$Sepal.Length[iris_data$Grp_Length == 0] <- NA

# Unpredictable NA actions

# This returns the expected answer
summary(iris_data$Sepal.Length)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA’s
5 5.5 6 6.041 6.5 7.9 22
# This doesnt return the expected answer
mean(iris_data$Sepal.Length)
## [1] NA
# This does
mean(iris_data$Sepal.Length, na.rm = TRUE)
## [1] 6.041406
# Option 1
iris_data$Grp_Length <- NULL

# Option 2 
iris_data <- iris_data[,-6]
1:5
## [1] 1 2 3 4 5
1:2
## [1] 1 2
1:5 + 1:2
## Warning in 1:5 + 1:2: longer object length is not a multiple of shorter
## object length
## [1] 2 4 4 6 6
# See whats going on - recycling...
# get a list of whats in the current environment

ls()
## [1] "iris_data"     "irisdata"      "irisdata2"     "irisMean"     
## [5] "NewCol2"       "originalNames" "sumTable"
# this erases everything in our environment

rm(list = ls(.GlobalEnv))

חומר קריאה לעומק

“Advanced R, Hadley Wickham, Chapters 1-4” at http://adv-r.had.co.nz/

“The R Inferno, Patrick Burns, Chapter 8” at http://www.burns-stat.com/documents/books/the-r-inferno/