איך קוראים box plot
Box plot דוחס התפלגות שלמה לחמישה מספרים ומצייר אותם כסימן קומפקטי אחד. לומדים לקרוא אותו בשלושים שניות, אז נתחיל בזה: לכל חלק יש משמעות מדויקת.
- הקו העבה בתוך הקופסה הוא החציון: חצי מהנתונים נמצאים מתחתיו, חצי מעליו.
- הקופסה עצמה משתרעת על הטווח הבין-רבעוני (IQR): מהרבעון הראשון (25% מהנתונים מתחתיו) עד הרבעון השלישי (75% מתחתיו). החצי האמצעי של הנתונים שלכם נמצא בתוך הקופסה.
- השפמים הם הקווים שיוצאים מהקופסה. כל אחד מגיע עד נקודת הנתונים הקיצונית ביותר שעדיין נמצאת בטווח של 1.5 × IQR משפת הקופסה, כך שהם מכסים את "הטווח הרגיל" של הנתונים, לא את הטווח המלא.
- נקודות בודדות מעבר לשפמים הן ערכים שרחוקים יותר מ-1.5 × IQR מהקופסה: הם מסומנים כחריגים חשודים ומצוירים אחד אחד כדי שתוכלו לספור אותם.
קופסה גבוהה פירושה נתונים מפוזרים; קו חציון שלא יושב במרכז הקופסה פירושו הטיה; שובל של נקודות מעבר לאחד השפמים פירושו זנב כבד בצד הזה. היסטוגרמה מראה את אותה התפלגות בפירוט רב יותר, אבל כוח העל של ה-box plot הוא שתריסר כאלה נכנסים זה לצד זה, וזה הופך אותו להגרף להשוואה בין קבוצות.
Boxplot של משתנה אחד
הפונקציה היא boxplot(), ועבור וקטור מספרי אחד זו קריאה אחת:
scores <- c(52, 55, 58, 60, 61, 63, 64, 66, 68, 70, 72, 95)
boxplot(scores,
main = "Test scores",
ylab = "Score")
התמונה שזה מצייר: קופסה מ-59 עד 69 עם קו חציון ב-63.5, שפמים שיורדים עד 52 ועולים עד 72, ונקודה בודדה אחת שמרחפת ב-95: החריג שסיכום של ממוצע וסטיית תקן היה בולע בשקט. התחושה המיידית ש"ערך אחד לא דומה לאחרים" היא בדיוק הסיבה שבשבילה יש box plots.
(כמו בכל עמוד בפרק הזה, קריאות השרטוט הן קטעי קוד סטטיים: הסביבה שמריצה את הקוד בהמשך מציגה פלט טקסט בלבד. הריצו אותן מקומית כדי לראות את הציור.)
השוואה בין קבוצות: ממשק הנוסחה
השימוש היומיומי האמיתי הוא קופסה אחת לכל קבוצה, ולשם כך boxplot() מקבלת נוסחה: y ~ group, שנקראת "y מפורק לפי group". מערך הנתונים המובנה של R, ToothGrowth, אורך שיניים של 60 שרקנים שקיבלו ויטמין C דרך מיץ תפוזים (OJ) או חומצה אסקורבית (VC), הוא ההדגמה הקלאסית:
boxplot(len ~ supp,
data = ToothGrowth,
main = "Tooth growth by supplement",
xlab = "Supplement",
ylab = "Tooth length")
מופיעות שתי קופסאות על סקאלה אנכית משותפת: הקופסה של OJ יושבת גבוה באופן בולט מהקופסה של VC, עם חציון של בערך 22 לעומת בערך 19. מכיוון ששתי הקופסאות חולקות ציר אחד, ההשוואה הוגנת מעצם הבנייה: אין סיכוי ששני גרפים עם סקאלות שונות יחמיאו לקבוצה אחת. עמודת הקיבוץ צריכה להיות factor (או וקטור תווים); כל רמה הופכת לקופסה אחת.
אפשר גם לקנן נוסחאות: boxplot(len ~ supp * dose, data = ToothGrowth) מצייר שש קופסאות, אחת לכל צירוף של תוסף ומינון. כשהבדל בין קבוצות נראה אמיתי בקופסאות, השאלה הטבעית הבאה, האם זה יותר מרעש, היא שאלה שמבחן t עונה עליה.
תוויות, צבעים ו-boxplots אופקיים
ארגומנטי העיצוב פועלים לפי המוסכמות של השרטוט הבסיסי. names נותן תוויות לקופסאות, col ממלא אותן: העבירו וקטור כדי לצבוע כל קבוצה בצבע אחר:
boxplot(len ~ supp,
data = ToothGrowth,
names = c("Orange juice", "Ascorbic acid"),
col = c("orange", "lightblue"),
main = "Tooth growth by supplement",
ylab = "Tooth length")
שני מתגים נוספים שווים את מקומם:
horizontal = TRUEמסובב את כל הגרף כך שהקופסאות נפרשות לאורך הציר האופקי. עשו זאת בכל פעם ששמות הקבוצות ארוכים: תוויות אופקיות נשארות קריאות במקום שבו תוויות אנכיות מתנגשות.notch = TRUEחורץ חריץ סביב כל חציון; כשהחריצים של שתי קבוצות לא חופפים, סביר שהחציונים שלהן שונים. התייחסו לזה כרמז חזותי, לא כמבחן.
המספרים שמאחורי הקופסה
כל מה שהגרף מצייר מגיע ממספרים שאפשר להדפיס. quantile() נותנת את סיכום חמשת המספרים, ו-boxplot.stats() נותנת לכם בדיוק את מה שהגרף משתמש בו, כולל החריגים. את זה אפשר להריץ כאן:
שימו לב שהשניים הם בני דודים, לא תאומים: quantile() מדווחת על המינימום והמקסימום האמיתיים, ואילו s$stats נגמר בשפמים, הנקודות הקיצוניות ביותר בתוך הגדר של 1.5 × IQR. הפער ביניהם הוא בדיוק s$out, כאן ה-95 הבודד. כשמישהו שואל "אילו שורות הן נקודות החריגים האלה?", x[x %in% boxplot.stats(x)$out], או סינון לפי ערכי הגדר, עונה על כך.
Boxplots עם ggplot2
ב-ggplot2 הקיבוץ נכנס למיפוי האסתטי במקום לנוסחה:
library(ggplot2)
ggplot(ToothGrowth, aes(x = supp, y = len, fill = supp)) +
geom_boxplot() +
labs(title = "Tooth growth by supplement",
x = "Supplement", y = "Tooth length")
אותן שתי קופסאות, עם מקרא ועיצוב בחינם. הגרסה של ggplot2 גדלה טוב יותר כשהגרף מסתבך: חלוקה ל-facets לפי dose, הצגת הנקודות הגולמיות מעל עם geom_jitter(width = 0.1), והקוד נשאר הצהרתי. להשוואה חד-פעמית במהלך ניתוח, boxplot(y ~ g, data = df) עדיין הדבר המהיר ביותר שאפשר להקליד.
מה לקחת מכאן
- אנטומיית הקופסה: קו חציון, קופסה = IQR, שפמים = הנקודות הקיצוניות ביותר בטווח 1.5 × IQR, נקודות מעבר לכך = חריגים חשודים.
boxplot(x)למשתנה אחד;boxplot(y ~ group, data = df)להשוואת קבוצות זו לצד זו על סקאלה משותפת והוגנת אחת.- עצבו עם
names, וקטורcolלכל קבוצה, ו-horizontal = TRUEכשהתוויות ארוכות. boxplot.stats(x)$statsו-$outהם הגרף בצורת מספרים: השתמשו בהם כדי לחלץ את החריגים שהגרף מצביע עליהם.- ggplot2:
geom_boxplot()כשהקבוצה ממופה ל-xאו ל-fill.
הבא בתור: תרשים הפיזור, מהתפלגות של משתנה אחד לקשר בין שניים.
שאלות נפוצות
איך יוצרים boxplot ב-R?
קראו ל-boxplot(x) עם וקטור מספרי כדי לקבל קופסה אחת, או השתמשו בממשק הנוסחה boxplot(y ~ group, data = df) כדי לקבל קופסה אחת לכל קבוצה, זו לצד זו. שתי האפשרויות מגיעות עם base R, בלי צורך בחבילות.
מה המשמעות של החלקים ב-box plot?
הקו העבה בתוך הקופסה הוא החציון. הקופסה משתרעת על הטווח הבין-רבעוני, מהרבעון הראשון עד השלישי. השפמים מגיעים עד נקודות הנתונים הקיצוניות ביותר שנמצאות בטווח של פי 1.5 מה-IQR מהקופסה, וכל מה שמעבר לשפמים מצויר כנקודה בודדת: חריג חשוד.
איך יוצרים boxplot לפי קבוצות ב-R?
השתמשו בנוסחה: boxplot(len ~ supp, data = ToothGrowth) מצייר קופסה אחת לכל רמה של supp. משתנה הקיבוץ צריך להיות עמודת factor או עמודת תווים; כל רמה הופכת לקופסה אחת על סקאלה משותפת.
איך מוצאים את החריגים שה-boxplot מראה?
boxplot.stats(x)$out מחזירה בדיוק את הערכים שהגרף היה מצייר כנקודות מעבר לשפמים, ו-boxplot.stats(x)$stats נותנת את חמשת המספרים שמאחורי הקופסה: קצות השפמים, צירי הקופסה והחציון.