Menu

וקטורים ב-R: c(), seq(), אינדקסים וחישוב וקטורי

וקטורים הם יחידת הבסיס של R, ואפילו מספר בודד הוא וקטור. איך יוצרים אותם עם c(), בוחרים איברים לפי אינדקס (מ-1!), מסננים עם מסכות לוגיות, ומחשבים על וקטורים שלמים בבת אחת.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

ב-R הכול וקטור

לרוב השפות יש סקלרים, ערכים בודדים, ואחר כך סוג מכל כלשהו שמחזיק כמה מהם. R מדלגת על הסקלר. וקטור הוא אוסף מסודר של ערכים שכולם מאותו סוג, והוא היחידה שכל השאר בנוי עליה. אפילו מה שנראה כמו מספר בודד הוא וקטור באורך 1:

c(), קיצור של combine, היא הדרך לבנות וקטור ביד. length() אומרת כמה איברים הוא מחזיק. ו-5 לבדו מדווח is.vector כ-TRUE עם אורך 1: R אף פעם לא מפסיקה לעבוד עם וקטורים, היא רק לפעמים עובדת עם וקטורים קצרים מאוד.

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

כלל אחד להפנים עכשיו: לכל האיברים בווקטור יש אותו סוג. אם נותנים ל-c() תערובת, היא לא מתלוננת: היא ממירה בשקט הכול לסוג הגמיש ביותר שקיים:

מחרוזת בתערובת הופכת הכול למחרוזות ("1", "TRUE"). ערכים לוגיים בין מספרים הופכים ל-1 ו-0. ההמרה הכפויה (coercion) הזאת עוקבת אחרי סדר עדיפויות קבוע, logical → integer → double → character, והיא קורית בלי אזהרה, ולכן "7" תועה בעמודה של מספרים יכול להפוך בשקט את כל מאגר הנתונים שלכם לטקסט. ההיררכיה המלאה מוסברת ב-סוגי נתונים; אם צריך להחזיק ערכים מעורבים באמת, בשביל זה יש רשימות.

יצירת סדרות: :, seq() ו-rep()

הקלדת כל איבר לתוך c() נמאסת מהר. ל-R יש שלושה קיצורי דרך לדפוסים קבועים:

  • 1:10 הוא היומיומי: מספרים שלמים מגבול אחד לשני, בקפיצות של 1.
  • seq() מכליל אותו: בחרו את הקפיצה עם by =, או אמרו כמה איברים אתם רוצים עם length.out = ותנו ל-R לחשב את המרווחים.
  • seq_len(n) מפיק 1 עד n והוא הדרך הבטוחה לבנות אינדקסים ללולאה: בניגוד ל-1:n, הוא נותן כראוי וקטור ריק כש-n הוא 0, במקום לספור 1 0 אחורה.
  • rep() חוזר על דברים: times = חוזר על כל הווקטור מקצה לקצה (1 2 1 2 1 2), each = חוזר על כל איבר במקומו (1 1 1 2 2 2). קל לבלבל ביניהם; הריצו את הקטע והשוו.

אינדקסים: R סופרת מ-1

סוגריים מרובעים שולפים איברים. האיבר הראשון הוא [1], לא [0]. אם אתם מגיעים מ-Python או מ-JavaScript, זו המעידה הנפוצה ביותר בהתחלה:

שלושה דברים כאן ששווה לעצור עליהם:

  • אפשר לבחור לפי וקטור של מיקומים: fruits[c(2, 4)] שולף את השני ואת הרביעי במכה אחת.
  • אינדקסים שליליים פירושם "הכול חוץ מ". fruits[-1] הוא הווקטור בלי האיבר הראשון שלו. זה שונה לגמרי מ-Python, שם -1 פירושו האיבר האחרון. אי אפשר לערבב אינדקסים חיוביים ושליליים באותה קריאה.
  • fruits[0] אינו שגיאה: הוא מחזיר character(0) ריק. באג של טעות באחד ב-R מפיק לעיתים קרובות תוצאות ריקות ושקטות ולא קריסה, ולכן כדאי לבדוק length() כשמשהו בהמשך נראה ריק באופן מסתורי.

לאיברים יכולים להיות גם שמות, וזה נותן דרך שלישית לבחור איברים: לפי תווית:

וקטורים עם שמות עובדים כמו טבלת חיפוש קלה ושומרים על קוד קריא: prices["tea"] אומר את מה שהוא מתכוון, prices[2] לא.

מסכות לוגיות ו-which()

הדרך החזקה ביותר לבחור איברים היא עם וקטור לוגי: מסכה של ערכי TRUE/FALSE באותו אורך כמו הנתונים. כל השוואה על וקטור מפיקה בדיוק את זה:

temps > 24 לא נותן תשובה אחת: הוא נותן חמש, אחת לכל איבר. הצבת המסכה הזאת בתוך [ ] משאירה את האיברים שבהם המסכה היא TRUE. שלבו תנאים עם & (וגם) ו-| (או), שמוסברים עם שאר ה-אופרטורים.

which() מתרגמת מסכה למיקומים: כאן 2 3 5, האינדקסים של המדידות החמות. השתמשו בה כשצריך לדעת איפה ההתאמות נמצאות: כדי לדווח עליהן, או כדי לבחור מווקטור אחר באותם מקומות. לסינון פשוט, temps[temps > 24] ישיר יותר מ-temps[which(temps > 24)].

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

חישוב וקטורי וכלל המחזור

חשבון ב-R חל איבר אחר איבר על וקטורים שלמים, בלי צורך בלולאה:

השורה הראשונה היא התכונה המרכזית: prices * 2 מכפיל כל איבר. במקום ששפות אחרות צריכות לולאת for, R צריכה אופרטור, והצורה הווקטורית גם קצרה יותר וגם מהירה יותר, כי הלולאה קורית בקוד C ממוטב מתחת לפני השטח. כתבו לולאת for כשכל שלב תלוי בקודם; לחישוב איבר אחר איבר, עבדו וקטורית.

השורה השלישית מדגימה את כלל המחזור: כשלווקטורים יש אורכים שונים, R חוזרת על הקצר כדי להתאים. c(10, 20) ממוחזר ל-10 20 10 20, ונותן 11 22 13 24. מחזור של 2 על פני וקטור באורך 3 הוא בדיוק מה שגרם ל-prices * 2 לעבוד: סקלר הוא פשוט וקטור באורך 1 שממוחזר.

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

מקבלים 11 22 13 ועוד אזהרה שאורך האובייקט הארוך אינו כפולה של אורך האובייקט הקצר. התייחסו לאזהרה הזאת כאל דיווח על באג: מחזור חלקי כמעט אף פעם אינו מה שהתכוונתם, ובדרך כלל הוא אומר ששני וקטורים שהיו אמורים להיות באותו אורך אינם כאלה.

מיון, היפוך, הסרת כפילויות

שלושה כלים קטנים שתשתמשו בהם כל הזמן:

sort() מסדרת את הערכים, rev() הופכת את הסדר הקיים בלי למיין, ו-unique() משמיטה כפילויות ושומרת את ההופעות הראשונות. אף אחת מהן לא משנה את x: כמו כמעט כל דבר ב-R, הן מחזירות וקטור חדש ומשאירות את המקור בשקט.

מה לקחת מכאן

  • וקטור הוא יחידת הבסיס של R: מסודר, מסוג אחד לכל אורכו, ואפילו ערכים בודדים הם וקטורים באורך 1.
  • בנו עם c(), ייצרו דפוסים עם :, seq() ו-rep(), וזכרו ש-c() ממירה בשקט סוגים מעורבים.
  • האינדקסים מתחילים מ-1; אינדקסים שליליים משמיטים איברים; שמות מאפשרים לבחור לפי תווית.
  • מסכות לוגיות (x[x > 5]) הן דרך הסינון של כל השפה; which() הופכת מסכה למיקומים.
  • החישוב וקטורי, וקטורים קצרים יותר ממוחזרים, ואזהרת מחזור חלקי אומרת שיש לכם באג.

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

שאלות נפוצות

איך יוצרים וקטור ב-R?

עם הפונקציה c() (קיצור של combine): x <- c(10, 20, 30). לסדרות קבועות, השתמשו ב-1:10, ב-seq(0, 1, by = 0.25) או ב-rep(0, 5). כל האיברים חייבים להיות בסוף מאותו סוג: אם מערבבים סוגים, R ממירה את כולם בשקט לסוג הגמיש ביותר.

האם האינדקסים ב-R מתחילים מ-0 או מ-1?

מ-1. x[1] הוא האיבר הראשון, x[length(x)] הוא האחרון. זה מפיל את כל מי שמגיע מ-Python, מ-JavaScript או מ-C: אין איבר x[0] (בקשה שלו מחזירה וקטור ריק, לא שגיאה, וזה הופך את הבאג לשקט).

מה עושה כלל המחזור (recycling) ב-R?

כשמבצעים חשבון על שני וקטורים באורכים שונים, R חוזרת על הקצר עד שהוא מתאים לארוך. c(1, 2, 3, 4) + c(10, 20) נותן 11 22 13 24. אם האורך הארוך אינו כפולה של הקצר, R עדיין מחשבת תשובה אבל מוציאה אזהרה: התייחסו לאזהרה הזאת כאל באג.

מה which() עושה ב-R?

היא ממירה וקטור לוגי למיקומים של ערכי ה-TRUE שלו. אם x > 5 נותן FALSE TRUE TRUE, אז which(x > 5) נותן 2 3. השתמשו בה כשצריך את המיקומים עצמם; לסינון פשוט, בחירה ישירה לפי הווקטור הלוגי (x[x > 5]) פשוטה יותר.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל