Menu

קריאת קובצי CSV ב-R (read.csv ו-read_csv)

איך מייבאים קובצי CSV ל-R עם read.csv(): הארגומנטים שחשובים, המלכודת של תיקיית העבודה שגורמת לרוב הכישלונות, ומתי readr::read_csv שווה את זה.

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

read.csv() הופכת קובץ CSV ל-data frame

קריאת CSV ב-R היא קריאה אחת לפונקציה, מובנית בשפה, בלי צורך בחבילה:

sales <- read.csv("sales.csv")

read.csv() קוראת את הקובץ, משתמשת בשורה הראשונה כשמות העמודות, מנחשת סוג לכל עמודה, ומחזירה data frame. זה כל הסיפור לקובץ מסודר.

אפשר לראות אותה עובדת בלי שום קובץ, כי read.csv() מקבלת גם טקסט CSV גולמי דרך הארגומנט text: אותו מנתח, שמקבל מחרוזת במקום שם קובץ:

str() היא הדבר הראשון שמריצים על כל דבר שמייבאים: היא מציגה כל עמודה עם הסוג שנוחש לה. כאן name הגיעה כ-character, score כ-integer, passed כ-logical, הכול נוחש מתוך הערכים. לבדיקה ויזואלית מהירה, head(students) מציגה את השורות הראשונות ו-nrow(students) סופרת אותן. אם עמודה שציפיתם שתהיה מספרית מופיעה כ-chr, משהו בעמודה הזאת אינו מספר: הערה תועה, "N/A", מפריד אלפים. זה הרגע לתקן, לא שלושה תרשימים אחר כך.

הארגומנטים שחשובים

ל-read.csv() יש עשרות פרמטרים; תשתמשו בבערך חמישה.

header: האם השורה הראשונה מכילה שמות עמודות. ברירת המחדל היא TRUE. אם הקובץ מתחיל ישר בנתונים, העבירו header = FALSE ו-R תקרא לעמודות V1, V2, ...

sep: מפריד השדות, ברירת המחדל ",". בחלק גדול מאירופה כותבים קובצי CSV עם נקודה-פסיק כמפריד, כי שם הפסיק הוא הנקודה העשרונית. R מגיעה עם גרסה מוגדרת מראש בדיוק לזה: read.csv2() משתמשת ב-sep = ";" וב-dec = ",":

הגבהים יוצאים כמספרים תקינים: read.csv2 ידעה ש-1,63 פירושו אחת נקודה שש שלוש. אם הייתם משתמשים ב-read.csv הרגילה על הקובץ הזה, הייתם מקבלים עמודה משובשת אחת, כי שום דבר לא מפצל נכון לפי פסיק שהוא בעצם נקודה עשרונית.

na.strings: אילו מחרוזות נחשבות לערך חסר. כברירת מחדל רק "NA" הופכת לערך חסר. קבצים שמיוצאים במציאות כותבים נתונים חסרים כתאים ריקים, "missing", "-", "NULL", ואם לא מצהירים עליהם, הם מגיעים כטקסט וגוררים את כל העמודה ל-character:

עם ה-na.strings הנכון, התאים הריקים הופכים ל-NA אמיתיים ו-score נשארת מספרית. בלעדיו, "missing" היא סתם מילה, והעמודה היא טקסט.

skip: כמה שורות לדלג לפני שהנתונים מתחילים. קבצים מיוצאים אוהבים לשים שורת כותרת או שתיים מעל הטבלה עצמה; skip = 2 קופץ מעליהן.

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

00501 הפך ל-501. הנתונים היו נכונים בקובץ ושגויים ב-R, בשקט. colClasses = c("integer", "character") אומר למנתח מה כל עמודה, לפי הסדר, והאפסים שורדים.

ארגומנט אחד שכבר לא צריך: stringsAsFactors. במשך רוב ההיסטוריה של R, read.csv() המירה כל עמודת טקסט ל-factor אלא אם אמרתם אחרת, וזה גרם לבלבול עצום. מאז R 4.0 ברירת המחדל היא FALSE: טקסט נשאר טקסט. עדיין תראו stringsAsFactors = FALSE פזור במדריכים ישנים; בגרסה עדכנית של R זה לא מזיק, אבל מיותר.

נתיבי קבצים: הסיבה מספר 1 לכישלון של read.csv

השגיאה שכל מי שלומד R פוגש בשבוע הראשון:

Error in file(file, "rt") : cannot open the connection
In addition: Warning message:
cannot open file 'sales.csv': No such file or directory

הקובץ קיים: אתם מסתכלים עליו בסייר הקבצים. אבל R לא מחפשת שם. שם קובץ חשוף כמו "sales.csv" מפוענח ביחס לתיקיית העבודה של R, ובדרך כלל זו לא התיקייה שבה נמצא הקובץ. שתי שורות מאבחנות את זה:

getwd()                    # where R is actually looking
file.exists("sales.csv")   # FALSE means the path is wrong, full stop

אם file.exists() אומרת FALSE, שום כמות של הרצות חוזרות לא תעזור: תקנו את הנתיב. או שתתנו נתיב מלא (read.csv("C:/Users/ada/data/sales.csv"): לוכסנים רגילים עובדים גם ב-Windows, ובטוחים יותר מלוכסנים הפוכים), או שתעבירו את תיקיית העבודה של R לתיקיית הנתונים עם setwd(). מהי תיקיית העבודה, איך פרויקטים מנהלים אותה, ולמה לא מקובל לשים setwd() בסקריפטים, מוסבר ב-תיקיית העבודה.

הפכו את file.exists() לרפלקס. היא הופכת "כישלון ייבוא מסתורי" ל"שגיאת הקלדה בנתיב" בשנייה אחת.

קריאת CSV ישירות מ-URL

read.csv() מקבלת URL בכל מקום שבו היא מקבלת שם קובץ, ומורידה את הקובץ בשבילכם:

url <- "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv"
penguins <- read.csv(url)
str(penguins)

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

readr::read_csv: החלופה המהירה והפטפטנית יותר

ה-tidyverse מגיע עם קורא CSV משלו בחבילה readr: read_csv() (קו תחתון, לא נקודה). כדאי להכיר אותה כי רוב קוד ה-R המודרני שתקראו משתמש בה:

install.packages("readr")   # once
library(readr)              # every session

flights <- read_csv("flights.csv")

ההבדלים המעשיים מ-read.csv():

  • מהירות: מהירה באופן מורגש בקבצים עם מאות אלפי שורות.
  • היא מחזירה tibble: data frame מודרני שמדפיס תצוגה מקדימה קומפקטית במקום להציף את הקונסולה.
  • היא מדווחת על הניחושים שלה: אחרי הקריאה היא מדפיסה את הסוג שזוהה לכל עמודה, כך שעמודה שנותחה כ-character כשציפיתם למספרים נראית מיד, במקום להפוך להפתעה בהמשך.
  • היא אף פעם לא משבשת שמות עמודות: read.csv() משכתבת כותרת כמו first name ל-first.name; read_csv() משאירה אותה כמו שהיא.

לקובץ קטן שתי הפונקציות בסדר. פנו ל-read_csv() כשהקבצים גדלים או כששאר הסקריפט שלכם כתוב ב-tidyverse בכל מקרה. כל מה שנאמר למעלה על נתיבים, מפרידים (גם read_csv2() קיימת) ומחרוזות של ערכים חסרים (na =) תקף גם כאן, עם שמות ארגומנטים קצת שונים.

כשמסיימים לנתח, הדרך חזרה החוצה, ייצוא התוצאות לקובץ, היא write.csv.

מה לקחת מכאן

  • df <- read.csv("file.csv") קוראת CSV ל-data frame; בדקו אותו מיד עם str() ו-head().
  • read.csv(text = "...") מנתחת מחרוזת CSV ישירות: מצוין לניסויים ולדוגמאות קטנות.
  • הארגומנטים שמצדיקים את קיומם: header, sep (או read.csv2 לנקודה-פסיק), na.strings, skip, colClasses.
  • "Cannot open file" אומר שתיקיית העבודה לא נמצאת איפה שאתם חושבים: getwd() ו-file.exists() מכריעות את זה מיד.
  • readr::read_csv() היא גרסת ה-tidyverse המהירה יותר: tibbles, דיווח על סוגי עמודות, שמות שלא נוגעים בהם.

הבא בתור: קבצים שהם בכלל לא טקסט פשוט. קריאת גיליונות Excel עם החבילה readxl.

שאלות נפוצות

איך קוראים קובץ CSV ב-R?

עם read.csv("file.csv"): היא מובנית, בלי צורך בחבילה. היא מחזירה data frame עם עמודה אחת לכל עמודה ב-CSV, ומשתמשת בשורה הראשונה כשמות העמודות. השימו את התוצאה במשתנה: df <- read.csv("sales.csv"), ואז בדקו אותה עם str(df) ו-head(df).

למה read.csv אומרת 'cannot open file: No such file or directory'?

R מחפשת את הקובץ ביחס לתיקיית העבודה שלה, שכנראה אינה התיקייה שבה נמצא הקובץ שלכם. הריצו getwd() כדי לראות איפה R מחפשת ו-file.exists("file.csv") כדי לאשר שהקובץ לא נמצא. תקנו עם נתיב מלא, או על ידי הגדרת תיקיית העבודה לתיקייה של הקובץ.

מה ההבדל בין read.csv ל-read_csv ב-R?

read.csv() היא חלק מ-R הבסיסית: תמיד זמינה, ומחזירה data frame רגיל. read_csv() מגיעה מהחבילה readr: היא מהירה יותר בקבצים גדולים, מחזירה tibble, אף פעם לא נוגעת בשמות העמודות, ומדפיסה את סוגי העמודות שניחשה כדי שתתפסו ניתוח שגוי מיד. לקבצים קטנים שתיהן בסדר; לקבצים גדולים או לשרשראות tidyverse, השתמשו ב-read_csv().

איך קוראים CSV שמופרד בנקודה-פסיק ב-R?

השתמשו ב-read.csv2("file.csv"): זו read.csv שמוגדרת מראש למוסכמה האירופית, נקודה-פסיק כמפריד ופסיק כנקודה עשרונית. או העבירו sep = ";" (ו-dec = "," אם צריך) ל-read.csv() הרגילה.

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

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

להתחיל