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

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

לצורך הדגמה זו, אשתמש בנתונים מסקר מפתחי Stack Overflow 2019, עם כ 90,000 תגובות. אם אתה רוצה לעקוב אחריו, אתה יכול להוריד את הנתונים מ- Stack Overflow.

אם חבילת data.table אינה מותקנת במערכת שלך, התקן אותה מ- CRAN ואז טען אותה כרגיל עם library(data.table). כדי להתחיל, כדאי לקרוא רק בשורות הראשונות של מערך הנתונים כדי להקל על בחינת מבנה הנתונים. אתה יכול לעשות זאת באמצעות fread()הפונקציה data.table nrowsוהוויכוח. אקרא בעשר שורות:

data_sample <- fread ("data / survey_results_public.csv", nrows = 10)

כפי שתראו, יש 85 עמודות לבדיקה. (אם אתה רוצה לדעת מה המשמעות של כל העמודות, יש קבצים בהורדה עם סכימת הנתונים וקובץ PDF של הסקר המקורי.) 

כדי לקרוא את כל הנתונים, אשתמש ב:

mydt <- fread ("data / survey_results_public.csv")

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

mydt [i, j, by]

המבוא לחבילה data.table אומר לקרוא את זה כ"קח שורות dt, קבוצה משנה או סדר מחדש באמצעות i, חשב j, מקובצות לפי ". זכור כי i ו- j דומים לסדר סוגריים בסיסי R: שורות ראשונות, עמודות שניות. אז אני מיועד לפעולות שתבצע בשורות (בחירת שורות על סמך מספרי שורות או תנאים); j זה מה שהיית עושה עם עמודות (בחר עמודות או צור עמודות חדשות מחישובים). עם זאת, שים לב שאתה יכול לעשות הרבה יותר סוגריים בתוך data.table מאשר מסגרת נתונים בסיסית R. והקטע "לפי" חדש ב- data.table.

מכיוון שאני בוחר עמודות, קוד זה נכנס למקום "j", מה שאומר שהסוגריים זקוקים לפסיק כדי להשאיר את נקודת "i" ריקה:

mydt [, j]

בחר עמודות data.table

אחד הדברים שאני אוהב ב- data.table הוא שקל לבחור עמודות בין ציטוטים או לא מצוטטים . לא מצוטט הוא לרוב נוח יותר (זו בדרך כלל הדרך המסודרת). אך הציטוט שימושי אם אתה משתמש ב- data.table בתוך הפונקציות שלך, או אם ברצונך להעביר וקטור שיצרת במקום אחר בקוד שלך.

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

dt1 <- mydt [, c ("LanguageWorkedWith", "LanguageDesireNextYear",

"OpenSourcer", "CurrencySymbol", "ConvertedComp",

"בעל תחביב")]

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

dt1 <- mydt [, list (LanguageWorkedWith, LanguageDesireNextYear,

OpenSourcer, CurrencySymbol, ConvertedComp,

בעל תחביב)]

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

dt1 <- mydt [,. (LanguageWorkedWith, LanguageDesireNextYear,

OpenSourcer, CurrencySymbol, ConvertedComp,

בעל תחביב)]

זהו .()קיצור דרך list()לסוגריים פנים data.table.

מה אם ברצונך להשתמש בווקטור שכבר קיים של שמות עמודות? הכנסת שם אובייקט הווקטורי לסוגריים data.table לא תעבוד. אם אני יוצר וקטור עם שמות עמודות מצוטטים, כך: 

mycols <- c ("LanguageWorkedWith", "LanguageDesireNextYear",

"OpenSourcer", "CurrencySymbol", "ConvertedComp", "Hobbyist")

אז קוד זה  לא יעבוד: 

dt1 <- mydt [, mycols]

במקום זאת, עליך להציב .. (זה שתי נקודות) מול שם האובייקט הווקטורי:

dt1 <- mydt [, ..mycols]

מדוע שתי נקודות? זה נראה לי די אקראי עד שקראתי את ההסבר. חשוב על זה כמו שתי הנקודות במסוף שורת הפקודה של יוניקס שמעלות אותך בספרייה אחת. כאן אתה מעלה מרחב שמות אחד , מהסביבה בתוך סוגריים data.table ועד הסביבה הגלובלית. (זה באמת עוזר לי לזכור את זה!)

ספירת שורות data.table

על הסמל הבא. כדי לספור לפי קבוצה, אתה יכול להשתמש .Nבסמל data.table , שם  .Nמייצג "מספר שורות". זה יכול להיות המספר הכולל של השורות, או מספר השורות לקבוצה אם אתה מצטבר בקטע "לפי". 

ביטוי זה מחזיר את מספר השורות הכולל ב- data.table: 

mydt [, .N]

הדוגמה הבאה מחשבת את מספר השורות המקובצות לפי משתנה אחד: האם אנשים בסקר מקודדים גם כתחביב ( Hobbyistהמשתנה).

mydt [, .N, תחביב]

# החזרות:

תחביב N 1: כן 71257 2: לא 17626

אתה יכול להשתמש בשם העמודה הרגילה בסוגריים data.table אם יש רק משתנה אחד. אם ברצונך לקבץ לפי שניים או יותר משתנים, השתמש .בסמל. לדוגמה:

mydt [, .N,. (הוביסט, OpenSourcer)]

להזמנת תוצאות מהגבוהה לנמוכה ביותר, ניתן להוסיף סט סוגריים שני אחרי הראשון. .Nהסמל יוצר באופן אוטומטי טור בשם N (כמובן שאתה יכול לשנות את זה אם אתה רוצה), כך הזמנה במספר השורות יכול להיראות בערך כך:

mydt [, .N,. (הוביסט, OpenSourcer)] [סדר (הוביסט, -N)]

כשאני לומד קוד data.table, אני מועיל לקרוא אותו שלב אחר שלב. אז הייתי קורא את זה בתור "עבור כל השורות mydt (מאז אין שום דבר 'הנקודה שאני'), לספור את מספר השורות, קיבוץ לפי תחביבים OpenSourcer. ואז הזמין תחילה על ידי הוביסט ואז מספר השורות היורדות. " 

זה שווה ערך לקוד dplyr זה:

mydf%>%

ספירה (הוביסט, OpenSourcer)%>%

סדר (הוביסט, -n)

אם הגישה הרב-קונבנציונאלית המסודרת של Tidyverse קריאה יותר לקריאה, קוד ה- data.table הזה עובד גם:

mydt [, .N,

(תחביב, OpenSourcer)] [

סדר (הוביסט, -N)

]

הוסף עמודות לטבלת data

לאחר מכן, ברצוני להוסיף עמודות כדי לראות אם כל מגיב משתמש ב- R, אם הוא משתמש ב- Python, אם הם משתמשים בשניהם, או אם הם לא משתמשים בשניהם. LanguageWorkedWithהעמודה יש מידע על שפות בשימוש, וכמה שורות של נתונים שנראות כמו זה:

שרון מכליס

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

כמו שקורה לעיתים קרובות, קל יותר לחפש פייתון מאשר R, מכיוון שלא ניתן לחפש רק "R" במחרוזת (רובי וחלודה מכילים גם אות גדולה) כמו שאתה יכול לחפש "פייתון". זהו הקוד הפשוט יותר ליצירת וקטור TRUE / FALSE שבודק אם כל מחרוזת LanguageWorkedWithמכילה Python:

ifelse (LanguageWorkedWith% like% "Python", TRUE, FALSE)

אם אתה מכיר SQL, תזהה תחביר "כמו". אני, ובכן, כמו %like%. שזו דרך יעילה ונחמדה לבדוק התאמת דפוסים. בתיעוד הפונקציה כתוב שהוא נועד לשימוש בתוך סוגריים data.table, אך למעשה אתה יכול להשתמש בו בכל אחד מהקודים שלך, לא רק עם data.tables. בדקתי עם היוצר של data.table מאט דאול, שאמר שהעצה להשתמש בו בסוגריים היא בגלל שקורה שם אופטימיזציה נוספת לביצועים.

לאחר מכן, הנה הקוד להוספת עמודה בשם PythonUser ל- data.table:

dt1 [, PythonUser: = ifelse (LanguageWorkedWith% like% "Python", TRUE, FALSE)]

שימו לב :=למפעיל. לפייתון יש גם מפעיל כזה, ומאז ששמעתי שהוא מכנה "מפעיל סוסים", זה מה שאני מכנה. אני חושב שזה באופן רשמי "מטלה לפי התייחסות". הסיבה לכך היא שהקוד שלמעלה שינה את האובייקט הקיים dt1 data.table על ידי הוספת העמודה החדשה - מבלי להזדקק לשמירה במשתנה חדש .

כדי לחפש R, אשתמש בביטוי הרגולרי "\\bR\\b"שאומר: “מצא תבנית שמתחילה בגבול מילים - \\bואז, ואז R, ואז מסתיים בגבול מילים אחר. (אני לא יכול לחפש סתם "R;" כי לפריט האחרון בכל מחרוזת אין נקודה-פסיק.) 

זה מוסיף עמודה RUser ל- dt1:

dt1 [, RUser: = ifelse (LanguageWorkedWith% like% "\\ bR \\ b", TRUE, FALSE)]

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

dt1 [, `: =` (

PythonUser = ifelse (LanguageWorkedWith% like% "Python", TRUE, FALSE),

RUser = ifelse (LanguageWorkedWith% like% "\\ bR \\ b", TRUE, FALSE)

]]

מפעילי טבלאות שימושיים יותר

ישנם מספר מפעילי שולחן נתונים נוספים שכדאי להכיר. %between% למפעיל יש תחביר זו:

myvector% בין% c (ערך נמוך יותר, ערך עליון)

אז אם אני רוצה לסנן את כל התגובות שבהן הפיצוי שולם בין 50,000 ל 100,000- דולר בדולרים אמריקאים, קוד זה עובד:

comp_50_100k <- dt1 [CurrencySymbol == "USD" &

ConvertedComp% בין% c (50000, 100000)]

השורה השנייה למעלה היא התנאי בין. שים לב %between%שהמפעיל כולל את הערכים התחתונים והעליונים כאשר הוא בודק.

מפעיל שימושי נוסף הוא %chin%. זה עובד כמו בסיס R %in%אבל מותאם למהירות והוא מיועד רק לווקטורי תווים . לכן, אם אני רוצה לסנן את כל השורות שבהן העמודה OpenSourcer הייתה "אף פעם" או "פחות מפעם אחת בשנה" קוד זה עובד:

rareos <- dt1 [OpenSourcer% chin% c ("אף פעם", "פחות מפעם אחת בשנה")]

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

rareos_df <- df1 [df1 $ OpenSourcer% ב-% c ("אף פעם", "פחות מפעם בשנה"),]

הפונקציה fcase () החדשה

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

usd <- dt1 [CurrencySymbol == "USD" &! is.na (ConvertedComp)]

לאחר מכן, אני אצור עמודה חדשה הנקראת Languageאם מישהו משתמש רק ב- R, רק בפייתון, בשניהם או באף אחד מהם. ואני אשתמש fcase()בפונקציה החדשה . בזמן פרסום מאמר זה fcase()היה זמין רק בגרסת הפיתוח של data.table. אם כבר התקנת data.table, תוכל לעדכן לגרסת dev האחרונה באמצעות פקודה זו: 

data.table :: update.dev.pkg ()

הפונקציה fcase () דומה CASE WHENלהצהרה של SQL ולפונקציה של dplyr case_when(). התחביר הבסיסי הוא  fcase(condition1, "value1", condition2, "value2")וכן הלאה. ניתן להוסיף ערך ברירת מחדל עבור "כל השאר" default = value.

הנה קוד ליצירת העמודה החדשה בשפה:

usd [, שפה: = fcase (

RUser &! PythonUser, "R",

PythonUser &! RUser, "Python",

PythonUser & RUser, "שניהם",

! PythonUser &! RUser, "גם לא"

]]

שמתי כל תנאי בשורה נפרדת כי קל יותר לקרוא אותי, אבל אתה לא צריך.

אזהרה: אם אתה משתמש ב- RStudio, מבנה data.table אינו מתעדכן אוטומטית בחלונית RStudio הימנית העליונה לאחר שתיצור עמודה חדשה עם מפעיל הסוסים. עליך ללחוץ ידנית על סמל הרענון כדי לראות שינויים במספר העמודות.

ישנם כמה סמלים אחרים שלא אעסוק במאמר זה. תוכל למצוא רשימה של אותם בקובץ העזרה "סמלים מיוחדים" בקבצי data.table על ידי הפעלה help("special-symbols"). לאחד מהשימושיים ביותר, .SD, כבר יש מאמר וסרטון Do More With R משלו, "כיצד להשתמש ב- .SD בחבילת R data.table."

לקבלת טיפים נוספים בנושא R, היכנס לדף "עשה יותר עם R" בדף או עיין בפלייליסט של YouTube "עשה יותר עם R".