這篇文章講 R Lang 中資料的輸入和輸出。R Lang 是一個統計導向型的程式設計語言,目的是統計和處理大量的複雜資料。因此在很多時候,R Lang 都將會被用來處理大型資料。對於真正的大型資料,我們通常是在資料庫軟體中或者是試算表軟體中存儲好外部檔案,然後再讓 R Lang 從外部檔案讀入進行處理。
資料框架
事實上,上一篇文章中有講到一種特殊的列表格式叫做資料框架(data frame)。我們說它就像是一個二維度表格一樣。因此,外部輸入的資料通常儲存在 data frame 的物件中。
舉一個例子,這是一份臨床試驗結果:
No | age | sex | DM | DMyr | preAC | prePC | postAC | postPC | Med | SIDE | PREKS |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 670 | 0 | 0 | 10 | 120 | 160 | 140 | 180 | 0 | 0 | 56 |
2 | 67 | 0 | 0 | 11 | 100 | 150 | 150 | 220 | 0 | 1 | 62 |
3 | 72 | 1 | 0 | 4 | 150 | 200 | 120 | 150 | 2 | 0 | 60 |
4 | 82 | 1 | 0 | 8 | 150 | 200 | 160 | 250 | 0 | 1 | 47 |
5 | 73 | 1 | 0 | 3 | 85 | 110 | 140 | 200 | 0 | 0 | 44 |
我們先來看一下資料框架有什麼特徵:
- 第1列(橫列,row),可以是變數的變數名(variable names)
- 第1列(row),有時是變數的欄位標籤(column label),而第2列(row)為變數名
- 每個變數各自形成1欄(縱行, column)
- 第1欄(縱行, column)為個體辨識碼(label, identification),或稱 列位標籤(row label)
- 每一欄(變數)的變數值形式可以是實數,文字,邏輯變數
- 第一欄(column)有時候是列位標籤 (row label)
- 變數名稱以英文為起始,之後可包含文字與數字,不可使用標點符號與空格。
- 變數值通常為數字,整數或文字,儘量避免直接輸入文字,因為大小寫,符號,空格的輸入經常造成錯誤
- 若原始資料沒有變數名或標籤,R Lang 讀入資料時可以同時輸入變數名,或讀入資料後,再輸入變數名
輸入外部 ASCII 資料檔
資料之間以空格分隔的資料檔
純文字的 ASCII 檔若以空格分開,則通常的副檔名為 .dat
或 .prn
或 .txt
。這類檔案通常直接由資料庫處理軟體輸出。
使用 read.table()
函式來進行讀取。該函式的定義如下:
不必為這一大堆引數而糟心。我們一個一個來看:
- file:需要 R Lang 讀取的自帶分隔符的 ASCII 檔案。絕對路徑或是相對於工作空間的相對路徑。
- header:logical 引數。表示檔案的第一列是否含有變數名。如果為 TRUE,要求第一列的欄數比資料列的數量少一欄。
- sep:分隔元。預設為
""
,表示一個或多個空格、tab、換行字元或迴車。 - quote:特殊字元的字串劃定接線的字串。預設為
"
或單引號'
。 - dec:資料中表示小數點的字元。預設為
.
。 - numerals:字串類型。用於指定文件中的數字轉換為雙精度資料時丟失精度的情況下如何進行轉換。
- row.names:儲存列名的向量。可以使用此參數以向量的形式給出每列的實際列名。或要讀取的表中包含列名稱的行序號或行名字串。在資料檔案中有列頭且首列的欄位名稱比資料欄少一個的情況下,資料檔案中第1欄將被視為欄位名稱。除此情況外,在沒有給定該參數時,讀取的列名將會自動編號。可以使用
row.names = NULL
強制列進行編號。 - col.names:指定欄名的向量。缺省時使用V+序號構成。
- as.is:此引數用於確定
read.table()
函式讀取字元型資料時是否轉換為因子型變數。當其取值為 FALSE 時,此函式將把字元型資料轉換為因子型資料,取值為 TRUE 時,仍將其保留為字元型。其取值可以是邏輯值向量(必要時可以循環賦值),數值型向量或字元型向量,以控制哪些列不會轉換為因子。 - na.strings:可選的用於表示缺失值的字元向量。
- colClasses:用於指定列所屬類別的字串向量。
- nrows:整數型數。用於指定從檔案讀取的最大行數。負數或其它無效值將會被忽略。
- skip:整數型數。讀取資料時忽略的行數。
- check.names:邏輯值。此引數值設定為 TRUE 時,資料框中的變數名稱將會被檢查,以確保符在語法上是有效的變數名稱。
- blank.lines.skip:邏輯值,此參數值設定為 TRUE 時,資料檔中的空白列將被忽略。預設值為 TRUE。
- fill:邏輯值。在沒有忽略空白行的情況下(即 blank.lines.skip=FLASE),且 fill 設定為 TRUE 時,如果資料檔案中某列的資料少於其他列,則自動新增空白域。
- strip.white:邏輯值,預設為 FALSE。此引數只在指定了 sep 因素時才有效。當此引數設定為 TRUE 時,資料檔案中沒有包圍的字串域的前邊和後邊的空格將會被去掉。
- comment.char:字元型。包含單一字元或空字元的向量。代表註解字元的開始字元。可以使用
""
關閉註解。 - allowEscapes:邏輯值。類似
\n
這種 C 風格的轉義符。如果這種轉義符並不是包含在字串中,則函式可能會解釋為欄位分隔符號。 - flush:邏輯值。預設值為 FALSE。 當此引數值設定為 TRUE 時,則函數讀取完指定列數後將轉到下一行。這允許用戶在最後一個字段後面添加註釋。
- stringAsFactors:邏輯值,標記處字元向量是否需要轉換為因子,預設是 TRUE。
- fileEncoding:字串類型,指定檔案的編碼方式。如果指定了該引數,則文字資料會依照指定的格式重新編碼。
- encoding:假定輸入字串的編碼方式。
- text:字串類型。當未提供 file 引數時,則函式可以透過一個文字連結從 text 讀取資料。
- skipNul:邏輯值。是否忽略空值。 預設為 FALSE。
大部分的引數保持預設值就好。我們來看一個例子:
資料之間以逗號分隔的資料檔
對於逗號分隔的資料檔,其副檔名通常為 .csv
。在讀取的時候我們依然可以使用 read.table()
函式,透過設定 sep
引數為逗號來進行讀取。另一種方法是透過 read.csv()
函式來讀取。該函式預設將分隔符設定成逗號。
載入和讀取 R Lang 內建資料框架和貢獻套件中的資料框架
R Lang 出於規範和示例的原因,已經為我們內建了許多資料框架。我們可以使用這些內建的資料框架來練習 R Lang 的作業。
可以使用 data()
函式來查看 R Lang 的內置資料框架。使用 head()
函式來查看資料框架的內容。
這兩個函式還有其他的作用。在其他貢獻套件中同樣有其內建的資料框架。使用 data()
函式就可以將這些資料框架載入,而使用 head()
函式可以讀取這些資料框架的內容。例如我們想要讀取 MASS 套件中的 VA 框架:
請注意,在 R Lang 的內建資料框架中,不需要 data()
載入即可使用 head()
讀取。而貢獻套件中的資料框架必須先載入,才能讀取。因為 R Lang 預設情況下不會認識這些貢獻的資料框架。
輸出 R Lang 資料
使用 write.table()
或 write.csv()
函式將 R Lang 的資料匯出到外部資料檔案。它們的引數如下:
- x = 匯出的 R Lang 物件名
- file = 路徑與檔案名稱
- append = FALSE 預設不在檔案末端附加資料
- quote = """ 預設文字變數值使用雙引號將
- sep = ” ” 預設空白分隔符號
- eol = “\n” 設定換行符號
- na = NA 設定 NA 符號
- dec = ’.’ 設定小數點符號
- row.names = TRUE 設定輸出 row names
- col.names = TRUE 設定輸出變數名(column names)
- qmethod = c(“escape”, “double”) 文字變數值有當引號時的分隔符號
- fileEncoding = "" 設定檔案編碼
輸出 Rds 格式的資料
對於大型資料集,如果存入普通的我外部資料檔中,每次讀取將耗費大量時間。而如果將 R Lang 中的 data frame 物件直接儲存成 Rds 格式,讀取就會快很多。
使用 saveRDS()
和 readRDS()
兩個函式來進行這個作業。