אחד מהפעולות החשובות בעבודה עם נתונים היא העברת מידע בצורה ברורה ותמציתית בעזרת טבלאות סיכום מלוטשות. בחבילות הבסיס של R יש כמה פקודות בסיסיות שעוזרות לצורך תחקור נתונים ומאפשרות ביצוע מבחנים סטטיסטיים שונים על נתונים. הנושאים האלה יועברו במצגת של טבלאות בנפרד, שתוכלו לעיין בו לבדכם. ב R קיימים הרבה מאוד חבילות שעוזרות ליצר טבלאות סיכום כאשר רובן מתקדמות בהנגשת תוצאות של מודלים סטטיסטיים ומעט מדי מהן מתקדמות ביצירת טבלאות רב ממדיות. עם זאת, בשנים האחרונות חלה שינוי במגמה הזאת וכעת מתחילים לצוץ כל מיני חבילות המשתמשות בשפות html ו java על מנת להעשיר את יכולת יצירת הטבלאות של R (כבר הכרנו את היכולות המרשימות של חבילת rPivottable
בשיעורים הקודמים). בשיעור הזה אנו נתמקד בחבילה אחת בשם pivottabler
על מנת לבנות טבלאות סיכום מוכנות להדפסה. הבחירה בחבילה זו הייתה בשל הפונקציונאליות והגמישות שהחבילה מאפשרת ובשל היכולת לשלוח נתונים ישירות ל html .
עד סוף השיעור תדעו איך:
בדומה לחבילות dplyr ו ggplot, גם חבילת pivottabler עובד על עיקרון של שכבות שבנויות אחת על גבי השנייה. אך בשונה מהחבילות הללו הסינטקס שלה יכולה להיות מאוד ארוכה ולא כל כך נוחה. למעשה ברוב השפות, ככל שנרצה לייצר טבלאות יותר מותאמות אישית, כך נשלם במחיר פשטות הכתיבה.
נתחיל בהתקנת הספרייה והטענת הספרייה לזיכרון:
library(pivottabler)
## Warning: package 'pivottabler' was built under R version 3.3.3
במקרה של טבלאות “פשוטות”, הפקודה qhpvt
תעשה לנו את כל העבודה בצורה נפלאה.
בעזת הפקודה הזאת אפשר ליצור טבלאות רב ממדיות עם כל חישוב אגרגטיבי שאנו מכירים מפקודת summarise
של dplyr
.
הסינטקס של הפקודה בצורה הרחבה שלה נראית כך:
qhpvt(dataFrame = dataTable
,rows = c("RowVar1", "RowVar2")
,columns = c("ColVar1", "ColVar2")
,calculations = c( "Calculation1 Label" = "SummaryFunction1"
,"Calculation2 Label" = "SummaryFunction2")
formats = list( "format1"
,"format2")
dataFrame
מקבל שם של טבלת נתוניםrows
ו columns
מקבלים שמות של עמודות לפיהן נרצה לייצר את הטבלה .calculations
יכול לקבל כל חישוב אגרגטיבי מחבילת dplyr
.formats
מתייחס לפורמטים שניתן לבחור באחד מפקודות הבסיס של R . ראו הסבר נרחב בעזרה על הפקודה sprintf
.הערה חשובה: חייבים לבטל כל group
שיש על טבלת נתונים לפני שמעבירים אותה לאחד מפקודות pivottabler
אחרת זה פשוט לא יעבוד
לדוגמא:
qhpvt(dataFrame = Santander_sample
, rows = "segmento"
, columns = "sexo"
, calculations = "mean(age, na.rm = TRUE)"
, formats = "%.2f")
## Warning: package 'bindrcpp' was built under R version 3.3.3
אם נחשב יותר מסטטיסטיקה אחת מומלץ לתת להם שמות, למשל:
qhpvt(dataFrame = Santander_sample
, rows = "segmento"
, columns = "sexo"
, calculations = c("Average Age" = "mean(age, na.rm = TRUE)"
,"Median Age" = "median(age, na.rm = TRUE)")
, formats = list("%.2f"))
ואם נרצה לפי כמה רמות בעמודות:
qhpvt(dataFrame = Santander_sample
, rows = "segmento"
, columns = c("ind_cc","sexo")
, calculations = c("Average Age" = "mean(age, na.rm = TRUE)"
,"Median Age" = "median(age, na.rm = TRUE)")
, formats = list("%.2f"))
ובשורות באותו אופן:
qhpvt(dataFrame = Santander_sample
, rows = c("fecha_dato", "segmento")
, columns = c("ind_cc","sexo")
, calculations = c("Average Age" = "mean(age, na.rm = TRUE)"
,"Median Age" = "median(age, na.rm = TRUE)")
, formats = list("%.2f"))
qhpvt(dataFrame = Santander_sample
, rows = c("segmento", "=")
, columns = c("ind_cc","sexo")
, calculations = c("Average Age" = "mean(age, na.rm = TRUE)"
,"Median Age" = "median(age, na.rm = TRUE)")
, formats = list("%.2f"))
לעומת :
qhpvt(dataFrame = Santander_sample
, rows = c( "=", "segmento")
, columns = c("ind_cc","sexo")
, calculations = c("Average Age" = "mean(age, na.rm = TRUE)"
,"Median Age" = "median(age, na.rm = TRUE)")
, formats = list("%.2f"))
לעומת :
qhpvt(dataFrame = Santander_sample
, rows = c("segmento")
, columns = c("ind_cc","=","sexo")
, calculations = c("Average Age" = "mean(age, na.rm = TRUE)"
,"Median Age" = "median(age, na.rm = TRUE)")
, formats = list("%.2f"))
בדוגמאות הקודמות שימו לב לדברים הבאים:
c()
format
אחד, והוא יושם רק על הסטטיסטיקה הראשונה, בהתאםכפי שראינו, בפקודה אחת יכולנו ליצור טבלה בצורה גמישה ומהירה, אבל לא יכולנו לשלוט בכל הפרמטרים. אם נרצה טבלאות מותאמות אישית נצטרך להשתמש בסינטקס המלא של החבילה.
השלבים שנעבור על מנת לייצר את הטבלה הם:
לרוב תעשו את כל השלבים אחד אחרי השני, אבל לשם הפשטות, נעבור על כל אחד מהשלבים בנפרד.
מגדירים אובייקט טבלה בעזרת הפקודה:
PivotTable$new()
באופן הבא:
pt <- PivotTable$new()
מוסיפים נתונים לטבלה בעזרת הפקודה:
addData()
באופן הבא:
pt <- PivotTable$new()
# New Line:
pt$addData(Santander_sample)
מוסיפים עמודות לטבלה בעזרת הפקודה:
addColumnDataGroups()
באופן הבא:
pt <- PivotTable$new()
pt$addData(Santander_sample)
# New Line:
pt$addColumnDataGroups("sexo")
pt <- PivotTable$new()
pt$addData(Santander_sample)
# New Line:
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc")
מוסיפים שורות לטבלה בעזרת הפקודה:
addRowDataGroups()
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc")
# New Line
pt$addRowDataGroups("segmento")
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc")
# New Line
pt$addRowDataGroups("segmento")
pt$addRowDataGroups("fecha_dato")
בשלב הבא מגדירים איזה חישובים אנו רוצים שיאכלסו את הטבלה. בהמשך נראה את סוגי החישובים השונים שניתן לשים בטבלה. מוסיפים ערך לחישוב בעזרת הפקודה הבאה:
defineCalculation( calculationName = “NameForRefference” ,caption =“NameForPrinting” ,summariseExpression = “summaryCommand” ,format = “format”)
calculationName
הוא לשימוש פנימי של המשתנה, כפי שנראה בהמשךcaption
נותן כותרת לעמודת החישוב במקרה שיש יותר מאחדsummariseExpression
יכול לקבל כל חישוב שאנו מכירים מחבילת dplyr
. המקרה הפשוט של ספירה הוא על ידי הפקודה n()
.format
מגדיר את תצורת ההדפסה של הערךלמשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc")
pt$addRowDataGroups("segmento")
pt$addRowDataGroups("fecha_dato")
# New Line
pt$defineCalculation( calculationName = "calcFreq"
,caption = "Frequencies"
,summariseExpression = "n()"
,format = "% 13d")
לבסוף יוצרים את הטבלה בעזרת הפקודה:
renderPivot()
כך:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc")
pt$addRowDataGroups("segmento")
pt$addRowDataGroups("fecha_dato")
pt$defineCalculation( calculationName = "calcFreq"
,caption = "Frequencies"
,summariseExpression = "n()"
, format = "%.0f")
# New Line
pt$renderPivot()
במקום להציג את הטבלה ניתן לשמור אותה ישירות לקובץ על ידי הרצת שתי הפקודות הבאות בסוף התהליך.
כך:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc")
pt$addRowDataGroups("segmento")
pt$addRowDataGroups("fecha_dato")
pt$defineCalculation( calculationName = "calcFreq"
,caption = "Frequencies"
,summariseExpression = "n()"
, format = "%.0f")
# New line
pt$evaluatePivot()
pt$saveHtml("C:\\somewhere\\Overthe\\Rainbow\\Output.html")
לחלופין, ניתן להדפיס את הטבלה ל Viewer
על ידי הרצת הפקודות ב console
, ומשם להשתמש ב Export
לשמור את הטבלה.
עד כה התייחסנו למקרה אחד של חישוב (חישוב אגרגטיבי) לאיכלוס נתוני הטבלה. למעשה יש כמה סוגי חישובים שניתן לעשות בעזרת החבילה:
אנו נעבור על שלושת הראשונים ונסביר את מהות הרביעית
כפי שראינו בדוגמאות הקודמות, ניתן להשתמש בכל חישוב אגרגטיבי שנרצה בעזרת הסינטקס:
defineCalculation( calculationName = “NameForRefference” ,caption =“NameForPrinting” ,summariseExpression = “summaryCommand” ,format = “format”)
כאשר, אם נרצה יותר מחישוב אחד נצטרך לכתוב כל אחד בפקודה נפרדת.
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addRowDataGroups("segmento")
pt$defineCalculation( calculationName = "clacAvgAge"
,caption ="Average Age"
,summariseExpression = "mean(age, na.rm=TRUE)"
,format = "%.2f")
pt$defineCalculation( calculationName = "clacMaxAge"
,caption ="Maximum Age"
,summariseExpression = "max(age, na.rm = TRUE)")
pt$defineCalculation( calculationName = "clacMinAge"
,caption ="Minimum Age"
,summariseExpression = "min(age, na.rm = TRUE)")
pt$renderPivot()
addRowCalculationGroups()
בסוף התהליך, למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addRowDataGroups("segmento")
pt$defineCalculation( calculationName = "clacAvgAge"
,caption ="Average Age"
,summariseExpression = "mean(age, na.rm=TRUE)"
,format = "%.2f")
pt$defineCalculation( calculationName = "clacMaxAge"
,caption ="Maximum Age"
,summariseExpression = "max(age, na.rm = TRUE)")
pt$defineCalculation( calculationName = "clacMinAge"
,caption ="Minimum Age"
,summariseExpression = "min(age, na.rm = TRUE)")
# New Line:
pt$addRowCalculationGroups()
pt$renderPivot()
באופן כללי הסדר בו אנו מוסיפים את השכבות קובע איפה הם יופיעו
למשל
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$defineCalculation( calculationName = "clacAvgAge"
,caption ="Average Age"
,summariseExpression = "mean(age, na.rm=TRUE)"
,format = "%.2f")
pt$defineCalculation( calculationName = "clacMaxAge"
,caption ="Maximum Age"
,summariseExpression = "max(age, na.rm = TRUE)")
pt$defineCalculation( calculationName = "clacMinAge"
,caption ="Minimum Age"
,summariseExpression = "min(age, na.rm = TRUE)")
pt$addRowCalculationGroups()
# New Line moved from above:
pt$addRowDataGroups("segmento")
pt$renderPivot()
ניתן להשתמש בעמודות מחושבות לצורך חישוב עמודה נוספת. נעשה זאת בעזרת הוספת הפרמטרים הבאים:
type=“calculation” ,basedOn = c(“calculationName1”,“calculationName2”) ,calculationExpression = " values$calculationName1 …"
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addRowDataGroups("segmento")
pt$defineCalculation( calculationName = "clacAvgAge"
,caption ="Average Age"
,summariseExpression = "mean(age, na.rm=TRUE)"
,format = "%.2f")
pt$defineCalculation( calculationName = "clacMaxAge"
,caption ="Maximum Age"
,summariseExpression = "max(age, na.rm = TRUE)")
pt$defineCalculation( calculationName = "clacMinAge"
,caption ="Minimum Age"
,summariseExpression = "min(age, na.rm = TRUE)")
# New Line
pt$defineCalculation( calculationName = "clacAgeRange"
,caption = "Years Between Oldest and Youngest"
,type="calculation"
,basedOn = c("clacMaxAge","clacMinAge")
,calculationExpression = " values$clacMaxAge - values$clacMinAge")
pt$renderPivot()
visible = FALSE
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addRowDataGroups("segmento")
pt$defineCalculation( calculationName = "clacAvgAge"
,caption ="Average Age"
,summariseExpression = "mean(age, na.rm=TRUE)"
,format = "%.2f")
pt$defineCalculation( calculationName = "clacMaxAge"
,caption ="Maximum Age"
,summariseExpression = "max(age, na.rm = TRUE)"
,visible = FALSE)
pt$defineCalculation( calculationName = "clacMinAge"
,caption ="Minimum Age"
,summariseExpression = "min(age, na.rm = TRUE)"
,visible = FALSE)
# New Line
pt$defineCalculation( calculationName = "clacAgeRange"
,caption = "Years Between Oldest and Youngest"
,type="calculation"
,basedOn = c("clacMaxAge","clacMinAge")
,calculationExpression = " values$clacMaxAge - values$clacMinAge")
pt$renderPivot()
הרבה פעמים נרצה פשוט להראות ערך ללא ביצוע חישוב מקדים. ניתן לעשות זאת על ידי סימון האופציות הבאות בתוך פקודת חישוב העמודה:
type=“value” valueName=“varName”
למשל:
renta_xseg <- Santander_sample %>%
group_by(sexo, segmento, ind_cc) %>%
summarise(avg_renta = mean(renta, na.rm = TRUE)) %>%
ungroup()
pt <- PivotTable$new()
pt$addData(renta_xseg)
pt$addColumnDataGroups("ind_cc")
pt$addColumnDataGroups("sexo")
pt$addRowDataGroups("segmento")
pt$defineCalculation(calculationName = "valRenta"
,caption = "Average Renta"
,type="value"
,valueName="avg_renta"
,format = "%.2f")
pt$renderPivot()
כפי שראיתם, במקרה כזה הסה“כ לא מחושב. על מנת לחשב אותו ניתן להוסיף פקודת summariseExpression אבל במקרה הזה זה יתן ממוצע של הממוצעים ולא את הממוצע הכללי…
pt <- PivotTable$new()
pt$addData(renta_xseg)
pt$addColumnDataGroups("ind_cc")
pt$addColumnDataGroups("sexo")
pt$addRowDataGroups("segmento")
pt$defineCalculation(calculationName = "valRenta"
,caption = "Average Renta"
,type="value"
,valueName="avg_renta"
,format = "%.2f"
#New line
,summariseExpression = "mean(avg_renta)")
pt$renderPivot()
חישובים מותאמים אישית מאפשרים הגדרת פונקציות על חישובי הטבלה והנתונים הגולמיים שנוכל לקרוא להם מתוך פקודת ה defineCalculation. הנושא מעבר לנושא השיעור אבל הקורא המעוניין מופנה ל vignette המצוין של החבילה.
יש מגוון אופציות אחרות שניתן לבצע על הטבלה. אנו נסקור רק חלק מהם.
ניתן לשלוט בכל מאפייני עמודות ושורות הסכימה בטבלה.
בכל שכבה ניתן לתת שם לעמודת הסכימה בעזרת האופציה:
totalCaption = “NewName”
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo", totalCaption = "סך הכל")
pt$addColumnDataGroups("ind_cc")
pt$addRowDataGroups("segmento", totalCaption = "סך הכל שורות")
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()")
pt$renderPivot()
ניתן להשמיט עמודות סכימה בכל שכבה בעזרת האופציה:
addTotal=False
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo", addTotal=FALSE)
pt$addColumnDataGroups("ind_cc", addTotal=FALSE)
pt$addRowDataGroups("segmento", addTotal=FALSE)
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()")
pt$renderPivot()
ניתן להרחיב את עמודת הסכימה שתכלול גם את השכבות הנמוכות יותר בעזרת הפרמטר:
expandExistingTotals = TRUE
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addColumnDataGroups("sexo")
pt$addColumnDataGroups("ind_cc", expandExistingTotals = TRUE)
pt$addRowDataGroups("segmento")
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()")
pt$renderPivot()
כברירת מחדל, חיתוכים בין משתנים שלא קיימים בנתונים אינם מוצגים.
ניתן לדרוש להציג אותם בעזרת השמת הפרמטר בשכבה הרלוונטית:
onlyCombinationsThatExist = FALSE
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addRowDataGroups("fecha_dato")
pt$addRowDataGroups("ind_cc", addTotal = FALSE, onlyCombinationsThatExist = FALSE)
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()")
pt$renderPivot()
במקרה הקודם, ובאופן כללי, ניתן להגדיר ערך ברירת מחדל עבור הצגה במקרה של ער כים ריקים.
noDataValue = number
noDataCaption = “symbol”
לדוגמא:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addRowDataGroups("fecha_dato")
pt$addRowDataGroups("ind_cc", addTotal = FALSE
, onlyCombinationsThatExist = FALSE)
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()"
, noDataCaption = "no value ")
pt$renderPivot()
ניתן להגדיר שרוצים להציג רק רמות מסוימות של משתנה. למשל, רק קבוצות גיל מסוימות, או רק פלחים ספציפיים מתוך האוכלוסייה.
נעשה זאת בעזרת הוספת הפרמטר הבא בשכבה המתאימה:
fromData = FALSE ,explicitListOfValues = list(“val1”, “val2”,…)
במקרים כאלה, מומלץ להוסיף לשכבה גם את הפרמטר:
visualTotals = TRUE
כך שעמודת הסכימה יחושב רק עבור הנתונים שמוצגים.
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addRowDataGroups("fecha_dato")
pt$addRowDataGroups("segmento"
# , fromData = FALSE
, explicitListOfValues = list("01 - TOP","03 - UNIVERSITARIO")
,visualTotals = TRUE)
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()"
, noDataCaption = "no value ")
pt$renderPivot()
בעזרת אותו פקודה ניתן גם לקבץ רמות של משתנה לקבוצה אחת.
למשל:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addRowDataGroups("fecha_dato")
pt$addRowDataGroups("segmento"
, fromData = FALSE
, explicitListOfValues = list(
"02 - PARTICULARES"
,"Other" = c("01 - TOP","03 - UNIVERSITARIO"))
,visualTotals = TRUE)
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()"
, noDataCaption = "no value ")
pt$renderPivot()
ניתן למיין את שורות או עמודות הטבלה על פי הערך המחושב באחת משתי דרכים:
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addRowDataGroups("fecha_dato")
pt$addRowDataGroups("segmento", dataSortOrder = "desc")
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()"
, noDataCaption = "no value ")
pt$renderPivot()
pt <- PivotTable$new()
pt$addData(Santander_sample)
pt$addRowDataGroups("fecha_dato")
pt$addRowDataGroups("segmento")
pt$defineCalculation(calculationName = "calcFreq"
, caption = "Freq"
, summariseExpression = "n()"
, noDataCaption = "no value ")
pt$sortRowDataGroups(levelNumber = 2, orderBy = "calculation", sortOrder = "asc")
pt$renderPivot()
למי שמעוניין יש עוד כמה נושאים כלליים שניתן לבצע בעזרת הספרייה, להלן סיכום תאור שלהם והפניה לפרק הרלוונטי ב vignete של החבילה: