這是匯入和匯出資料至 R 的指南。
本手冊適用於 R 4.3.3 版(2024-02-29)。
版權所有 © 2000–2023 R 核心團隊
只要在所有副本上保留版權公告和此許可公告,即授予製作和散發本手冊逐字副本的許可。
只要整個衍生作品在與本許可公告相同的許可公告條款下散發,即授予在逐字複製條件下複製和散發本手冊修改版本的許可。
只要此許可公告可以用 R 核心團隊核准的翻譯版本陳述,即授予在修改版本上述條件下複製和散發本手冊翻譯版本的許可,但此許可公告可以翻譯版本陳述。
本手冊的關聯式資料庫部分,部分根據 Douglas Bates 和 Saikat DebRoy 早期的手冊。本手冊的主要作者是 Brian Ripley。
許多志工為這裡使用的套件做出貢獻。以下列出所提及套件的主要作者
- DBI:
David A. James
- dataframes2xls:
Guido van Steen
- foreign:
Thomas Lumley、Saikat DebRoy、Douglas Bates、Duncan Murdoch 和 Roger Bivand
- gdata:
Gregory R. Warnes
- ncdf4:
David Pierce
- rJava:
Simon Urbanek
- RJDBC:
Simon Urbanek
- RMySQL:
David James 和 Saikat DebRoy
- RNetCDF:
Pavel Michna
- RODBC:
Michael Lapsley 和 Brian Ripley
- ROracle:
David A. James
- RPostgreSQL:
Sameer Kumar Prayaga 和 Tomoaki Nishiyama
- RSPerl:
Duncan Temple Lang
- RSPython:
Duncan Temple Lang
- RSQLite:
David A. James
- SJava:
John Chambers 和 Duncan Temple Lang
- WriteXLS:
Marc Schwartz
- XLConnect:
Mirai Solutions GmbH
- XML:
Duncan Temple Lang
Brian Ripley 是連線支援的作者。
將資料讀取到統計系統中進行分析,並將結果匯出到其他系統中撰寫報告,可能會令人沮喪,而且花費的時間可能遠遠超過統計分析本身,儘管大多數讀者會發現後者更具吸引力。
本手冊說明 R 自身或透過 CRAN 或其他地方取得的套件可用的匯入和匯出功能。
除非另有說明,本手冊中所述的一切(至少在原則上)可在執行 R 的所有平台上使用。
一般而言,像 R 這樣的統計系統並不特別適合處理大規模資料。其他一些系統比 R 更擅長這方面,本手冊的一部分重點在於建議,我們可以讓另一個系統執行工作,而不是在 R 中重複功能!(例如,Therneau & Grambsch (2000) 評論說,他們偏好使用 SAS 執行資料處理,然後在 S 中使用套件 survival 進行分析。)資料庫處理系統通常非常適合處理和擷取資料:此處討論了幾個與 DBMS 互動的套件。
有套件允許以 Java
、perl
和 python
等語言開發的功能與 R 程式碼直接整合,讓使用這些語言中的功能更為合適。(請參閱 CRAN 中的 rJava 套件。)
另外值得記住的是,R 和 S 一樣,源自於 Unix 的小型可重複使用工具傳統,在匯入或匯出之前或之後,使用 awk
和 perl
等工具來處理資料可能會很有收穫。Becker、Chambers 和 Wilks (1988,第 9 章) 中的案例研究就是一個例子,其中使用 Unix 工具在輸入 S 之前檢查和處理資料。傳統的 Unix 工具現在更廣泛地可用,包括 Windows。
本手冊最初寫於 2000 年,從那時起 R 套件的數量和範圍已增加了一百倍。對於特殊資料格式,值得搜尋看看是否已有適當的套件。
匯入 R 中最簡單的資料格式是純文字檔,這通常適用於中小型問題。匯入文字檔的主要函式為 scan
,而 試算表格式資料 中所討論的許多較方便的函式都是基於此函式。
然而,所有統計顧問都曾遇過客戶拿著隨身碟(以前是軟碟或 CD-R)來,裡面裝著某些專有二進位格式的資料,例如「Excel 試算表」或「SPSS 檔案」。通常最簡單的做法是使用原始應用程式將資料匯出為文字檔(而統計顧問的電腦中通常會安裝最常見的應用程式,以備不時之需)。不過,這並不總是可行,而 從其他統計系統匯入 會討論如何直接從 R 存取此類檔案。至於 Excel 試算表,可用方法已在 讀取 Excel 試算表 中做總結。
在某些情況下,資料會以二進位格式儲存,以求精簡和加快存取速度。我們多次見過的一個應用是影像資料,通常會儲存為記憶體中所表示的位元組串流,前面可能加上標頭。此類資料格式會在 二進位檔案 和 二進位連線 中討論。
對於較大的資料庫,使用資料庫管理系統 (DBMS) 來處理資料是很常見的。再次有使用 DBMS 來萃取純文字檔案的選項,但對於許多這樣的 DBMS,萃取操作可以直接從 R 套件執行:請參閱 關聯式資料庫。透過網路連線匯入資料會在 網路介面 中討論。
除非要匯入的檔案完全使用 ASCII,通常有必要知道它是如何編碼的。對於文字檔案,找出其結構的良好方法是 file
命令列工具(對於 Windows,包含在 Rtools
中)。這會回報類似
text.Rd: UTF-8 Unicode English text text2.dat: ISO-8859 English text text3.dat: Little-endian UTF-16 Unicode English character data, with CRLF line terminators intro.dat: UTF-8 Unicode text intro.dat: UTF-8 Unicode (with BOM) text
包含 macOS 在內的現代類 Unix 系統可能會產生 UTF-8 檔案。Windows 可能會產生它所謂的「Unicode」檔案(UCS-2LE
或可能只是 UTF-16LE
1)。否則,大多數檔案將會使用 8 位元編碼,除非來自中/日/韓地區設定(它們有廣泛使用的編碼)。無法自動確定使用哪種 8 位元編碼(儘管可以猜測,file
可能會像在上述範例中那樣猜測),因此您可能必須詢問建立者一些線索(例如「Windows 上的俄語」)。
「BOM」(位元組順序標記,https://zh.wikipedia.org/wiki/%E5%8D%83%E7%B4%9A%E9%A0%86%E5%BA%8F%E6%A8%99%E8%A8%98)會導致 Unicode 檔案出現問題。在 Unix 世界中,BOM 很少使用,而在 Windows 世界中,UCS-2/UTF-16 檔案幾乎總是使用 BOM,UTF-8 檔案也經常使用。沒有 BOM 的 UCS-2 檔案甚至無法被 file
程式識別,但許多其他程式會拒絕讀取有 BOM 的檔案,而 IANA 的 UTF-16LE
和 UTF-16BE
標準也禁止使用 BOM。我們經常被迫使用命令列程式 od
或十六進位編輯器來查看檔案,才能找出其編碼。
請注意,utf8
不是有效的編碼名稱(UTF-8
才有效),而 macintosh
是有時稱為「Mac Roman」編碼的最具可攜性的名稱。
從 R 匯出結果通常是項較不具爭議性的任務,但仍有許多潛在的陷阱。會有一個目標應用程式,而文字檔通常是最方便的交換媒介。(如果需要二進位檔,請參閱二進位檔。)
函數 cat
是用於匯出資料的函數的基礎。它需要一個 file
參數,而 append
參數允許透過連續呼叫 cat
來寫入文字檔。更好的方法,特別是如果需要執行多次,是開啟一個 file
連線以進行寫入或附加,然後將 cat
放入該連線中,再將其 close
。
最常見的任務是將矩陣或資料框寫入檔案,作為數字的矩形網格,可能包含列標籤和欄標籤。這可以使用函數 write.table
和 write
來完成。函數 write
只會寫出一個矩陣或向量,並指定欄位數(並轉置矩陣)。函數 write.table
更方便,並會寫出一個資料框(或可以轉換為資料框的物件),並包含列標籤和欄標籤。
將資料框寫入文字檔案時,有許多問題需要考慮。
這些函數執行的實數/複數轉換大多是完全精度的,但 write
的轉換會受到 options(digits)
目前設定的控制。若要進一步控制,請對資料框使用 format
,可能逐欄執行。
R 偏好標題列沒有列名稱的項目,因此檔案看起來像
dist climb time Greenmantle 2.5 650 16.083 ...
其他一些系統需要一個(可能為空)的列名稱項目,如果指定引數 col.names = NA
,write.table
會提供這個項目。Excel 就是這樣的系統之一。
檔案中常用的欄位分隔符號是逗號,因為在英語系國家中,逗號不太可能出現在任何欄位中。此類檔案稱為 CSV(逗號分隔值)檔案,包裝函式 write.csv
提供適當的預設值。在某些地區,逗號用作小數點(在 write.table
中透過 dec = ","
設定),而 CSV 檔案則使用分號作為欄位分隔符號:使用 write.csv2
以取得適當的預設值。有一個針對 CSV 檔案的 IETF 標準(強制使用逗號和 CRLF 行尾,使用 eol = "\r\n"
),RFC4180(請參閱 https://www.rfc-editor.org/rfc/rfc4180),但實際上更重要的是檔案是否可供目標應用程式讀取。
使用分號或 tab (sep = "\t"
) 可能是最安全的選項。
預設情況下,遺失值會輸出為 NA
,但這可以用參數 na
變更。請注意,NaN
會由 write.table
視為 NA
,但 cat
和 write
則不會。
預設情況下,字串會加上引號(包括列和欄位名稱)。參數 quote
控制字元和因子變數是否加上引號:例如,有些程式(例如 Mondrian (https://en.wikipedia.org/wiki/Mondrian_(software))),不接受加上引號的字串。
如果字串包含嵌入式引號,則需要特別小心。有三個有用的形式
> df <- data.frame(a = I("a \" quote")) > write.table(df) "a" "1" "a \" quote" > write.table(df, qmethod = "double") "a" "1" "a "" quote" > write.table(df, quote = FALSE, sep = ",") a 1,a " quote
第二個形式是試算表常用的跳脫形式。
文字檔案不包含其編碼的元資料,因此對於非 ASCII 資料,檔案需要設定目標為打算讀取它的應用程式。所有這些函式都可以寫入 連線,允許為檔案指定編碼,而 write.table
有 fileEncoding
參數,讓這件事更容易。
困難的部分是知道要使用什麼檔案編碼。要在 Windows 上使用,最好使用 Windows 稱之為「Unicode」2 的編碼,也就是 "UTF-16LE"
。使用 UTF-8 是製作可攜式檔案的好方法,不會輕易與任何其他編碼混淆,但即使是 macOS 應用程式(UTF-8 是其系統編碼)可能也無法辨識它們,而 Windows 應用程式更是極不可能辨識。顯然 Excel:mac 2004/8 預期 .csv
檔案使用 "macroman"
編碼(Mac OS 早期版本中使用的編碼)。
套件 MASS 中的函式 write.matrix
提供寫入矩陣的專用介面,並提供分區寫入矩陣的選項,從而減少記憶體使用量。
可以使用 sink
將標準 R 輸出導向檔案,從而擷取(可能是隱含的)print
陳述式的輸出。這通常不是最有效率的途徑,而且可能需要增加 options(width)
設定。
套件 foreign 中的函式 write.foreign
使用 write.table
產生文字檔案,並寫入一個程式碼檔案,將這個文字檔案讀入另一個統計套件。目前支援匯出至 SAS
、SPSS
和 Stata
。
從文字檔讀取資料時,使用者有責任了解並指定用於建立該檔案的慣例,例如註解字元、是否有標題列、值分隔符號、遺失值的表示方式(等等),如 匯出至文字檔 中所述。一種標記語言可用於描述內容以及內容結構,讓檔案成為自我描述,因此無需向讀取資料的軟體提供這些詳細資訊。
可擴充標記語言(更常簡稱為 XML)可用於提供此類結構,不僅適用於標準資料集,也適用於更複雜的資料結構。XML 變得非常流行,並成為一般資料標記和交換的標準。它正被不同的社群用於描述地理資料,例如地圖、圖形顯示、數學等等。
XML 提供一種方式來指定檔案的編碼,例如
<?xml version="1.0" encoding="UTF-8"?>
儘管它並不要求這樣做。
XML 套件提供一般功能,用於在 R 中讀取和寫入 XML 文件。CRAN 上的套件 StatDataML 是建立在 XML 上的一個範例。套件 xml2 提供了另一個介面,用於 libxml2 C 函式庫。
yaml 是另一個用於建構文字資料的系統,強調人類可讀性:它由套件 yaml 支援。
在 匯出至文字檔 中,我們看到了試算表式文字檔格式的許多變化,其中資料以矩形格線呈現,可能包含列標籤和欄標籤。在本節中,我們考慮將此類檔案匯入 R。
read.table
的變化 ¶函數 read.table
是讀取矩形資料格線最方便的方法。由於可能性很多,因此還有其他幾個函數會呼叫 read.table
,但會變更一組預設引數。
請注意,read.table
是讀取非常大的數值矩陣時效率不高的方式:請參閱下方的 scan
。
需要考慮的一些問題包括
如果檔案包含非 ASCII 字元欄位,請確保以正確的編碼讀取。這主要是指在 UTF-8 區域設定中讀取 Latin-1 檔案的問題,這可以用類似的方式來處理
read.table("file.dat", fileEncoding="latin1")
請注意,這將在任何可以表示 Latin-1 字串的區域設定中運作,但許多希臘語/俄語/中文/日語…區域設定不行。
我們建議您明確指定 header
參數。慣例上,標題列只為欄位提供項目,不為列標籤提供項目,因此比其他列短一個欄位。(如果 R 看到了這一點,它會設定 header = TRUE
。)如果提供一個標題欄位(可能是空的)給列標籤的檔案,請使用類似的方式讀取
read.table("file.dat", header = TRUE, row.names = 1)
欄位名稱可以透過 col.names
明確給出;明確名稱會覆寫標題列(如果存在)。
通常查看檔案會決定要使用的欄位分隔符號,但對於空白分隔的檔案,預設 sep = ""
(使用任何空白(空格、標籤或換行)作為分隔符號)、sep = " "
和 sep = "\t"
之間可能會有選擇。請注意,分隔符號的選擇會影響引號字串的輸入。
如果您有一個包含空白欄位的 tab 分隔檔案,請務必使用 sep = "\t"
。
預設上,字元字串可以用 ‘"’ 或 ‘'’ 引號,而且在每個情況下,所有到配對引號的字元都會視為字元字串的一部分。有效的引號字元組(可能沒有)由 quote
參數控制。對於 sep = "\n"
,預設值會變更為 quote = ""
。
如果未指定分隔符號,則可以在引號內字串中透過在引號前加上「\」來跳脫引號,這是 C 式風格。
如果指定了分隔符號,則可以在引號內字串中透過加倍引號來跳脫引號,這是試算表中慣用的方式。例如
'One string isn''t two',"one more"
可以用
read.table("testfile", sep = ",")
來讀取,這不適用於預設分隔符號。
預設情況下,假設檔案包含字串 NA
來表示遺失值,但這可以用引數 na.strings
來變更,此引數是一個向量,其中包含一個或多個遺失值的字元表示。
數字欄位中的空白欄位也會視為遺失值。
在數字欄位中,會接受值 NaN
、Inf
和 -Inf
。
從試算表匯出的檔案通常會省略所有尾隨的空白欄位(及其分隔符號)。若要讀取此類檔案,請設定 fill = TRUE
。
如果指定了分隔符號,則字元欄位中的前導和尾隨空白會視為欄位的一部分。若要移除空白,請使用引數 strip.white = TRUE
。
預設情況下,read.table
會忽略空白列。這可以用設定 blank.lines.skip = FALSE
來變更,這僅會與 fill = TRUE
搭配使用時才有用,或許可以用空白列來表示規則配置中遺失的案例。
除非採取任何特殊動作,否則 read.table
會將所有欄位讀取為字元向量,然後嘗試為資料框中的每個變數選擇適當的類別。它會依序嘗試 logical
、integer
、numeric
和 complex
,如果任何輸入都不遺失且無法轉換,則繼續進行。3 如果以上所有都失敗,則會將變數轉換為因子。
參數 colClasses
和 as.is
提供更佳的控制。指定 as.is = TRUE
會抑制字元向量的轉換為因子(僅限)。使用 colClasses
允許為輸入中的每一欄設定所需的類別:它會更快且使用更少的記憶體。
請注意,colClasses
和 as.is
是以 每 一欄指定,而非 每 一個變數,因此包括列名稱的欄(若有)。
預設情況下,read.table
使用 ‘#’ 作為註解字元,如果遇到此字元(引號字串中除外),則會忽略該行的其餘部分。僅包含空白和註解的列會被視為空白列。
如果已知資料檔案中沒有註解,則使用 comment.char = ""
會更安全(且可能更快)。
許多作業系統有慣例將反斜線用作文字檔案中的跳脫字元,但 Windows 沒有(且在路徑名稱中使用反斜線)。在 R 中是否將此類慣例套用至資料檔案是可選擇的。
read.table
和 scan
都有一個邏輯參數 allowEscapes
。預設為 false,且反斜線僅會被解釋為(在上述情況下)跳脫引號。如果將其設定為 true,則會解釋 C 風格的跳脫字元,即控制字元 \a, \b, \f, \n, \r, \t, \v
以及八進位和十六進位表示法,例如 \040
和 \0x2A
。任何其他跳脫字元都會被視為其本身,包括反斜線。請注意,Unicode 跳脫字元,例如 \uxxxx
,永遠不會被解釋。
這可以用 fileEncoding
參數指定,例如
fileEncoding = "UCS-2LE" # Windows ‘Unicode’ files fileEncoding = "UTF-8"
如果你(正確地)知道檔案編碼,這幾乎總是可行的。不過,我們知道有一個例外,帶有 BOM 的 UTF-8 檔案。有些人聲稱 UTF-8 檔案不應該有 BOM,但有些軟體(顯然包括 Excel:mac)會使用它們,而且許多類 Unix 作業系統不接受它們。因此,面對 file
報告為
intro.dat: UTF-8 Unicode (with BOM) text
的檔案,可以在 Windows 上透過
read.table("intro.dat", fileEncoding = "UTF-8")
讀取,但在類 Unix 作業系統上可能需要
read.table("intro.dat", fileEncoding = "UTF-8-BOM")
(這在 UTF-8 區域設定中不指定編碼時很可能會起作用。)
方便函式 read.csv
和 read.delim
提供參數給 read.table
,適用於從英語系區域設定中的試算表匯出的 CSV 和分隔符號分隔的檔案。變體 read.csv2
和 read.delim2
適用於使用逗號作為小數點,以及(對於 read.csv2
)使用分號分隔欄位的試算表的區域設定中使用。
如果 read.table
的選項指定不正確,錯誤訊息通常會是
Error in scan(file = file, what = what, sep = sep, : line 1 did not have 5 elements
或
Error in read.table("files.dat", header = TRUE) : more columns than column names
這可能會提供足夠的資訊來找出問題,但輔助函式 count.fields
可以用於進一步調查。
在讀取大型資料網格時,效率很重要。指定 comment.char = ""
、colClasses
為每個欄位的原子向量類型(邏輯、整數、數字、複數、字元或可能是原始)以及提供 nrows
(要讀取的列數)(而且輕微的高估比完全不指定要好)會有幫助。請參閱後續章節中的範例。
有時資料檔案沒有欄位分隔符號,但欄位位於預先指定的欄中。在穿孔卡的時代,這是很常見的,現在有時仍用於節省檔案空間。
函數 read.fwf
提供一個簡單的方法來讀取此類檔案,指定欄位寬度的向量。此函數將檔案讀入記憶體中作為整行,分割產生的字元字串,寫出一個暫時的 tab 分隔檔案,然後呼叫 read.table
。這對於小型檔案來說已經足夠了,但對於任何更複雜的檔案,我們建議使用類似 perl
的語言的工具來預先處理檔案。
函數 read.fortran
是固定格式檔案的類似函數,使用 Fortran 樣式的欄位規格。
有時用於試算表格式資料的舊格式是 DIF,或資料交換格式。
函數 read.DIF
提供一個簡單的方法來讀取此類檔案。它採用類似於 read.table
的引數來指定每個欄的類型。
在 Windows 上,試算表程式經常將複製到剪貼簿的試算表資料儲存在此格式中;read.DIF("clipboard")
可以直接從中讀取。在處理具有空白儲存格的試算表時,它比 read.table("clipboard")
稍為強健。
scan
¶read.table
和 read.fwf
都使用 scan
來讀取檔案,然後處理 scan
的結果。它們非常方便,但有時最好直接使用 scan
。
函數 scan
有許多引數,其中大部分我們已於 read.table
中討論過。最重要的引數是 what
,它指定要從檔案讀取的變數模式清單。如果清單有命名,則名稱會用於傳回清單的組成部分。模式可以是數字、字元或複雜的,通常由範例指定,例如 0
、""
或 0i
。例如
cat("2 3 5 7", "11 13 17 19", file="ex.dat", sep="\n") scan(file="ex.dat", what=list(x=0, y="", z=0), flush=TRUE)
傳回一個有三個組成部分的清單,並捨棄檔案中的第四欄。
有一個函數 readLines
,如果您只想將整行讀入 R 以供進一步處理,它會更方便。
一個 scan
常見的用途是讀取大型矩陣。假設檔案 matrix.dat 僅包含 200 x 2000 矩陣的數字。然後我們可以使用
A <- matrix(scan("matrix.dat", n = 200*2000), 200, 2000, byrow = TRUE)
在一個測試中,這花費 1 秒(在 Linux 下,在同一台機器上的 Windows 下花費 3 秒),而
A <- as.matrix(read.table("matrix.dat"))
花費 10 秒(以及更多記憶體),而
A <- as.matrix(read.table("matrix.dat", header = FALSE, nrows = 200, comment.char = "", colClasses = "numeric"))
花費 7 秒。差異幾乎完全是因讀取 2000 個獨立的短欄所產生的負擔:如果它們的長度為 2000,scan
花費 9 秒,而 read.table
在有效率地使用(特別是,指定 colClasses
)時花費 18 秒,在單純地使用時花費 125 秒。
請注意,計時可能會取決於所讀取的類型和資料。考慮讀取一百萬個不同的整數
writeLines(as.character((1+1e6):2e6), "ints.dat") xi <- scan("ints.dat", what=integer(0), n=1e6) # 0.77s xn <- scan("ints.dat", what=numeric(0), n=1e6) # 0.93s xc <- scan("ints.dat", what=character(0), n=1e6) # 0.85s xf <- as.factor(xc) # 2.2s DF <- read.table("ints.dat") # 4.5s
以及一百萬個小組代碼範例
code <- c("LMH", "SJC", "CHCH", "SPC", "SOM") writeLines(sample(code, 1e6, replace=TRUE), "code.dat") y <- scan("code.dat", what=character(0), n=1e6) # 0.44s yf <- as.factor(y) # 0.21s DF <- read.table("code.dat") # 4.9s DF <- read.table("code.dat", nrows=1e6) # 3.6s
請注意,這些計時在很大程度上取決於作業系統(Windows 中的基本讀取至少比這些 Linux 時間長兩倍)以及垃圾收集器的精確狀態。
有時候,試算表資料會以一種緊湊的格式呈現,提供每個受試者的協變數,接著是對該受試者的所有觀察值。R 的建模函數需要將觀察值放在單一欄中。考慮以下重複 MRI 大腦測量資料的範例
Status Age V1 V2 V3 V4 P 23646 45190 50333 55166 56271 CC 26174 35535 38227 37911 41184 CC 27723 25691 25712 26144 26398 CC 27193 30949 29693 29754 30772 CC 24370 50542 51966 54341 54273 CC 28359 58591 58803 59435 61292 CC 25136 45801 45389 47197 47126
有兩個協變數和每個主體最多四個測量。資料從 Excel 匯出為檔案 mr.csv。
我們可以使用 stack
來幫助處理這些資料,以提供單一回應。
zz <- read.csv("mr.csv", strip.white = TRUE) zzz <- cbind(zz[gl(nrow(zz), 1, 4*nrow(zz)), 1:2], stack(zz[, 3:6]))
結果如下
Status Age values ind X1 P 23646 45190 V1 X2 CC 26174 35535 V1 X3 CC 27723 25691 V1 X4 CC 27193 30949 V1 X5 CC 24370 50542 V1 X6 CC 28359 58591 V1 X7 CC 25136 45801 V1 X11 P 23646 50333 V2 ...
函數 unstack
朝相反方向進行,可能有助於匯出資料。
另一個執行此操作的方法是使用函數 reshape
,透過
> reshape(zz, idvar="id",timevar="var", varying=list(c("V1","V2","V3","V4")),direction="long") Status Age var V1 id 1.1 P 23646 1 45190 1 2.1 CC 26174 1 35535 2 3.1 CC 27723 1 25691 3 4.1 CC 27193 1 30949 4 5.1 CC 24370 1 50542 5 6.1 CC 28359 1 58591 6 7.1 CC 25136 1 45801 7 1.2 P 23646 2 50333 1 2.2 CC 26174 2 38227 2 ...
函數 reshape
的語法比 stack
複雜,但可用於「長」格式資料,其中資料欄位多於此範例中的欄位。使用 direction="wide"
,reshape
也可以執行相反的轉換。
有些人偏好套件 reshape、reshape2 和 plyr 中的工具。
以陣列形式顯示高維度列聯表通常相當不方便。在分類資料分析中,此類資訊通常以有邊界的二維陣列形式表示,其中前導列和欄指定對應於儲存格計數的因子層級組合。這些列和欄通常是「參差不齊」的,因為標籤僅在變更時顯示,並遵循明顯的慣例,即從上到下讀取列,從左到右讀取欄。在 R 中,可以使用 ftable
建立此類「平面」列聯表, 它會建立類別為 "ftable"
的物件,並具有適當的列印方法。
作為一個簡單範例,考慮 R 標準資料集 UCBAdmissions
,它是一個三度列聯表,來自於 1973 年加州大學柏克萊分校六個最大系所的研究所申請者,依錄取與性別分類。
> data(UCBAdmissions) > ftable(UCBAdmissions) Dept A B C D E F Admit Gender Admitted Male 512 353 120 138 53 22 Female 89 17 202 131 94 24 Rejected Male 313 207 205 279 138 351 Female 19 8 391 244 299 317
列印表示法明顯比將資料顯示為三度陣列更有用。
還有一個函數 read.ftable
用於從檔案讀取類平面列聯表。 對於如何精確表示列和欄位變數名稱和層級的資訊,它有額外的參數來處理變異。 read.ftable
的說明頁面有一些有用的範例。平面表格可以使用 as.table
轉換成陣列形式的標準列聯表。
請注意,平面表格的特徵是其列 (和可能還有欄位) 標籤的「參差不齊」顯示。如果給出列變數層級的完整網格,則應該改用 read.table
讀取資料,並使用 xtabs
從中建立列聯表。
在本章中,我們考慮讀取由其他統計系統寫入的二進位資料檔的問題。通常最好避免這樣做,但如果原始系統不可用,則可能無法避免。
在所有情況下,所描述的工具都是針對特定版本其他系統的資料檔所寫的 (通常在 2000 年代初期),而且不一定已更新為最新版本的其他系統。
建議套件 foreign 提供匯入這些統計系統產生的檔案,以及匯出到 Stata 的功能。在某些情況下,這些函數所需的記憶體可能大幅少於 read.table
。 write.foreign
(請參閱 匯出到文字檔案)提供匯出機制,目前支援 SAS
、SPSS
和 Stata
。
EpiInfo 版本 5 和 6 將資料儲存在自述式固定寬度文字格式中。 read.epiinfo
會將這些 .REC 檔案讀取到 R 資料框中。EpiData 也會產生這種格式的資料。
函數 read.mtp
會匯入「Minitab 可攜式工作表」。這會將工作表的組成部分傳回為 R 清單。
函數 read.xport
會讀取 SAS 傳輸 (XPORT) 格式的檔案,並傳回資料框清單。如果系統中有 SAS,可以使用函數 read.ssd
來建立並執行 SAS 腳本,將 SAS 永久資料集 (.ssd 或 .sas7bdat) 儲存為傳輸格式。然後它會呼叫 read.xport
來讀取產生的檔案。(套件 Hmisc 有類似的函數 sas.get
,也會執行 SAS。)對於無法使用 SAS 但執行 Windows 的人來說,SAS 系統檢視器(可免費下載)可用於開啟 SAS 資料集,並將其匯出為例如 .csv 格式。
函數 read.S
可以讀取 S-PLUS 3.x、4.x 或 2000 在 (32 位元) Unix 或 Windows 上產生的二進位物件(並可以在不同的作業系統上讀取)。這能夠讀取許多但並非所有 S 物件:特別是它可以讀取向量、矩陣和資料框,以及包含這些內容的清單。
函數 data.restore
讀取 S-PLUS 資料傾印(由 data.dump
建立),具有相同的限制(但也可以讀取 Alpha 平台的傾印)。應該可以讀取 S-PLUS 5.x 和更新版本使用 data.dump(oldStyle=T)
編寫的資料傾印。
如果您有權存取 S-PLUS,通常在 S-PLUS 中 dump
物件,然後在 R 中 source
傾印檔案會比較可靠。對於 S-PLUS 5.x 和更新版本,您可能需要使用 dump(..., oldStyle=T)
,而要讀取非常大的物件,最好將傾印檔案用作批次指令碼,而不是使用 source
函數。
函數 read.spss
可以讀取 SPSS 中的「儲存」和「匯出」指令建立的檔案。它會傳回一個清單,其中每個儲存資料集中的變數有一個元件。SPSS 具有值標籤的變數會選擇性地轉換為 R 因子。
SPSS 資料輸入是一個用於建立資料輸入表單的應用程式。預設情況下,它會建立具有 read.spss
無法處理的額外格式化資訊的資料檔案,但可以將資料匯出為一般 SPSS 格式。
一些第三方應用程式宣稱以「SPSS 格式」產生資料,但格式有差異:read.spss
可能可以或可能無法處理這些資料。
Stata .dta 檔案是一種二進位檔案格式。Stata 5 到 12 版本的檔案可以用函式 read.dta
和 write.dta
讀取和寫入。具有值標籤的 Stata 變數可以選擇轉換成 (和從) R 因子。對於 Stata 13 和後續版本,請參閱 CRAN 套件 readstata13 和 haven。
read.systat
會讀取那些矩形資料檔 (mtype = 1
) 的 Systat SAVE
檔案,這些檔案寫入於小端序機器 (例如 Windows) 中。這些檔案的副檔名為 .sys 或 (較新的) .syd。
Octave 是數值線性代數系統 (https://octave.org/),套件 foreign 中的函式 read.octave
可以讀取使用 Octave 指令 save -ascii
建立的 Octave 文字資料格式檔案,並支援大部分常見的變數類型,包括標準原子 (實數和複數純量、矩陣和 N 維陣列、字串、範圍,以及布林純量和矩陣) 和遞迴 (結構、儲存格和清單) 型態。
R 處理資料的類型有其限制。由於 R 處理的所有資料都存在於記憶體中,而且在執行函數期間可能會建立多份資料副本,因此 R 不適合處理極大型的資料集。超過 (幾) 百 MB 的資料物件可能會導致 R 記憶體不足,特別是在 32 位元作業系統上。
R 不容易支援同時存取資料。也就是說,如果有多位使用者存取,甚至更新相同的資料,一位使用者所做的變更對其他使用者來說將不可見。
R 確實支援資料的持續性,您可以從一個工作階段儲存資料物件或整個工作表,並在後續工作階段還原,但儲存資料的格式特定於 R,其他系統不容易處理。
資料庫管理系統 (DBMS),特別是關聯式資料庫管理系統 (RDBMS) 被設計成能處理所有這些事情。它們的優點是
DBMS 可能用於提取 10% 的資料樣本、交叉製表資料以產生多維度列聯表,以及從資料庫中按組提取資料以進行個別分析等統計應用程式。
由於這些原因,作業系統本身越來越頻繁地使用 DBMS,因此現在很可能在您的(非 Windows)作業系統上已經安裝了 DBMS。KDE4 使用 Akonadi 來儲存個人資訊。多個 macOS 應用程式,包括郵件和通訊錄,使用 SQLite。
傳統上,一直有大型(且昂貴)的商用 RDBMS(Informix;Oracle;Sybase;IBM 的 DB2;Microsoft SQL Server 在 Windows 上)以及學術和小型系統資料庫(例如 MySQL4、PostgreSQL、Microsoft Access,…),前者以更強調資料安全性功能為特點。隨著 MySQL 和 PostgreSQL 擁有越來越多的高階功能,以及商用 DBMS 提供免費的「快速」版本,界線變得模糊。
還有其他常用的資料來源,包括試算表、非關聯式資料庫,甚至文字檔(可能是壓縮的)。開放式資料庫連線(ODBC)是一個用於所有這些資料來源的標準。它起源於 Windows(請參閱 https://docs.microsoft.com/zh-tw/sql/odbc/microsoft-open-database-connectivity-odbc),但也在 Linux/Unix/macOS 上實作。
本章節稍後描述的所有套件都提供客戶端到客戶端/伺服器資料庫的客戶端。資料庫可以駐留在同一台機器上,或(更常)遠端。有一個 ISO 標準(事實上好幾個:SQL92 是 ISO/IEC 9075,也稱為 ANSI X3.135-1992,而 SQL99 已開始使用)用於稱為 SQL(結構化查詢語言,有時發音為「sequel」:請參閱 Bowman 等人 1996 年和 Kline 與 Kline 2001 年)的介面語言,這些 DBMS 在不同程度上支援這些語言。
更全面的 R 介面會在幕後為常見操作產生 SQL,但所有介面在複雜操作中都需要直接使用 SQL。慣例上 SQL 以大寫寫成,但許多使用者會覺得在 R 介面函式中使用小寫更方便。
關聯式 DBMS 將資料儲存在資料庫中,資料庫由資料表(或關聯)組成,這些資料表與 R 資料框相當類似,因為它們由欄或欄位(數值、字元、日期、貨幣,…)和列或記錄(包含一個實體的觀察結果)組成。
SQL「查詢」是針對關聯式資料庫執行的相當通用的操作。傳統的查詢是 SELECT 陳述式,類型如下:
SELECT State, Murder FROM USArrests WHERE Rape > 30 ORDER BY Murder SELECT t.sch, c.meanses, t.sex, t.achieve FROM student as t, school as c WHERE t.sch = c.id SELECT sex, COUNT(*) FROM student GROUP BY sex SELECT sch, AVG(sestat) FROM student GROUP BY sch LIMIT 10
這些第一個選項從 R 資料結構 USArrests
選取兩個欄位,已複製到資料庫表格中,在第三個欄位中進行子集化,並要求對結果進行排序。第二個選項對兩個表格 student
和 school
執行資料庫 join,並傳回四個欄位。第三個和第四個查詢執行一些交叉分類,並傳回計數或平均值。(五個聚合函數為 COUNT(*) 和 SUM、MAX、MIN 和 AVG,每個函數都套用於單一欄位。)
SELECT 查詢使用 FROM 選取表格,WHERE 指定包含條件(或多個條件,以 AND 或 OR 分隔),並使用 ORDER BY 對結果進行排序。與資料結構不同,RDBMS 表格中的列最好視為未排序,且沒有 ORDER BY 陳述式,排序是不確定的。您可以透過逗號分隔多個欄位,以(按字典順序)對其進行排序。在 ORDER BY 之後加上 DESC,會將排序設為降冪。
SELECT DISTINCT 查詢只會傳回所選表格中每個不同列的一個副本。
GROUP BY 子句根據準則選取列的子群組。如果指定多個欄位(以逗號分隔),則可以使用五個聚合函數之一來摘要多向交叉分類。HAVING 子句允許選取包含或排除群組,具體取決於聚合值。
如果 SELECT 陳述式包含產生唯一排序的 ORDER BY 陳述式,則可以新增 LIMIT 子句來選取(按數字)一組連續的輸出列。這有助於一次擷取一組列。(除非排序是唯一的,否則可能不可靠,因為 LIMIT 子句可用于最佳化查詢。)
有查詢可建立資料表(CREATE TABLE,但通常在這些介面中會將資料框複製到資料庫中)、INSERT 或 DELETE 或 UPDATE 資料。資料表會被 DROP TABLE『查詢』摧毀。
Kline 和 Kline(2001)討論了 SQL 在 Microsoft SQL Server 2000、Oracle、MySQL 和 PostgreSQL 中的實作細節。
資料可以儲存在資料庫中,並使用各種資料類型。資料類型的範圍取決於 DBMS,但 SQL 標準定義了許多類型,包括以下廣泛實作的類型(通常不是使用 SQL 名稱)。
float(p)
實數,具有可選精度。通常稱為 real
或 double
或 double precision
。
integer
32 位元整數。通常稱為 int
。
smallint
16 位元整數
character(n)
固定長度字元字串。通常稱為 char
。
character varying(n)
可變長度字元字串。通常稱為 varchar
。幾乎總是限制在 255 個字元。
boolean
真或假。有時稱為 bool
或 bit
。
date
日曆日期
time
一天中的時間
timestamp
日期和時間
在 time
和 timestamp
中有變體,with timezone
。其他廣泛實作的類型為 text
和 blob
,分別用於儲存大區塊文字和二進位資料。
更全面的 R 介面套件會對使用者隱藏類型轉換問題。
在 CRAN 上有許多可用套件,協助 R 與 DBMS 通訊。它們提供不同層級的抽象。有些提供將整個資料框複製至資料庫或從資料庫複製資料的方法。所有套件都具有透過 SQL 查詢在資料庫中選取資料的功能,並將結果作為一個整體擷取為資料框或分批擷取(通常為群組列)。
除了 RODBC 之外,所有套件都與一個 DBMS 連結,但已提出一個統一的「前端」套件 DBI (https://developer.r-project.org/db/),搭配一個「後端」,其中最開發完成的是 RMySQL。在 CRAN 上還有後端 ROracle、RPostgreSQL 和 RSQLite(與綑綁的 DBMS SQLite
搭配使用,https://www.sqlite.org/index.html),以及 RJDBC(使用 Java,可以連線到任何具有 JDBC 驅動程式的 DBMS)。
PL/R (https://github.com/postgres-plr/plr) 是將 R 嵌入 PostgreSQL 的專案。
套件 RMongo 提供 R 介面,連線到「MongoDB」(https://en.wikipedia.org/wiki/MongoDB) 資料庫的 Java 程式客戶端,該資料庫使用 JavaScript 而不是 SQL 進行查詢。套件 mongolite 是另一個使用 mongodb 的 C 驅動程式的客戶端。
套件 RMySQL 在 CRAN 上提供一個介面連接 MySQL 資料庫系統(請參閱 https://mysql.dev.org.tw 和 Dubois,2000 年)或其分支 MariaDB(請參閱 https://mariadb.org/)。此處的說明適用於 0.5-0
和後續版本:較早的版本有實質上不同的介面。目前版本需要 DBI 套件,而此說明會對 DBI 所有其他後端進行微小的變更。
MySQL 存在於 Unix/Linux/macOS 和 Windows 上:有一個在 GPL 下發行的「社群版本」,但也有商業授權可用。MySQL 最初是一個「輕量精簡」的資料庫。(它會保留名稱的大小寫,而作業系統檔案系統會區分大小寫,因此不適用於 Windows。)
呼叫 dbDriver("MySQL")
會傳回一個資料庫連線管理員物件,然後呼叫 dbConnect
會開啟一個資料庫連線,之後可以呼叫通用函式 dbDisconnect
來關閉。請使用 dbDriver("Oracle")
、dbDriver("PostgreSQL")
或 dbDriver("SQLite")
搭配這些 DBMS 和套件 ROracle、RPostgreSQL 或 RSQLite。
SQL 查詢可透過 dbSendQuery
或 dbGetQuery
傳送。 dbGetquery
會傳送查詢並將結果擷取為資料框。 dbSendQuery
會傳送查詢並傳回繼承自 "DBIResult"
的類別物件,可用於擷取結果,然後在呼叫 dbClearResult
時用於移除結果。
函式 fetch
用於以清單形式擷取查詢結果中部分或全部列。函式 dbHasCompleted
指出是否已擷取所有列,而 dbGetRowCount
會傳回結果中的列數。
這些是方便的介面,可用於讀取/寫入/測試/刪除資料庫中的資料表。 dbReadTable
和 dbWriteTable
會複製至 R 資料框或從 R 資料框複製,並將資料框的列名稱對應到 MySQL
資料表中的欄位 row_names
。
> library(RMySQL) # will load DBI as well ## open a connection to a MySQL database > con <- dbConnect(dbDriver("MySQL"), dbname = "test") ## list the tables in the database > dbListTables(con) ## load a data frame into the database, deleting any existing copy > data(USArrests) > dbWriteTable(con, "arrests", USArrests, overwrite = TRUE) TRUE > dbListTables(con) [1] "arrests" ## get the whole table > dbReadTable(con, "arrests") Murder Assault UrbanPop Rape Alabama 13.2 236 58 21.2 Alaska 10.0 263 48 44.5 Arizona 8.1 294 80 31.0 Arkansas 8.8 190 50 19.5 ... ## Select from the loaded table > dbGetQuery(con, paste("select row_names, Murder from arrests", "where Rape > 30 order by Murder")) row_names Murder 1 Colorado 7.9 2 Arizona 8.1 3 California 9.0 4 Alaska 10.0 5 New Mexico 11.4 6 Michigan 12.1 7 Nevada 12.2 8 Florida 15.4 > dbRemoveTable(con, "arrests") > dbDisconnect(con)
套件 RODBC 在 CRAN 上提供一個介面給支援 ODBC 介面的資料庫來源。這非常廣泛地被使用,並允許相同的 R 程式碼存取不同的資料庫系統。 RODBC 可在 Unix/Linux、Windows 和 macOS 上執行,而且幾乎所有的資料庫系統都支援 ODBC。我們已在 Windows 上測試過 Microsoft SQL Server、Access、MySQL、PostgreSQL、Oracle 和 IBM DB2,以及在 Linux 上測試過 MySQL、MariaDB、Oracle、PostgreSQL 和 SQLite。
ODBC 是一個客戶端伺服器系統,我們很樂意從 Windows 客戶端連線到在 Unix 伺服器上執行的 DBMS,反之亦然。
在 Windows 上,ODBC 支援是作業系統的一部分。在 Unix/Linux 上,您需要一個 ODBC 驅動程式管理員,例如 unixODBC (https://www.unixodbc.org/) 或 iOBDC (https://www.iodbc.org/:這已預先安裝在 macOS 中),以及一個已安裝的驅動程式給您的資料庫系統。
Windows 不僅提供給 DBMS 的驅動程式,也提供給 Excel (.xls) 試算表、DBase (.dbf) 檔案,甚至文字檔案。(這些應用程式不需要安裝。支援哪些檔案格式取決於驅動程式的版本。)有支援 Excel 和 Access 2007/2010 的版本(請前往 https://www.microsoft.com/en-us/download/default.aspx,並搜尋「Office ODBC」,這將會導向 AccessDatabaseEngine.exe),「2007 Office 系統驅動程式」(後者有 64 位元 Windows 版本,而且也可以讀取較早的版本)。
在 macOS 上,Actual Technologies (https://www.actualtech.com/product_access.php) 驅動程式提供 ODBC 介面給 Access 資料庫和 Excel 試算表(不包括 Excel 2007/2010)。
可以同時進行多個連線。連線是透過呼叫 odbcConnect
或 odbcDriverConnect
開啟的(在 Windows GUI 上,允許透過對話方塊選取資料庫),它會傳回一個用於後續存取資料庫的句柄。列印連線會提供一些 ODBC 連線的詳細資料,而呼叫 odbcGetInfo
會提供客戶端和伺服器的詳細資料。
連線是透過呼叫 close
或 odbcClose
關閉的,而且(會發出警告)當沒有 R 物件參照它時,以及在 R 工作階段結束時也會關閉。
連線上的表格詳細資料可以使用 sqlTables
找到。
函式 sqlSave
會將 R 資料框複製到資料庫中的表格,而 sqlFetch
會將資料庫中的表格複製到 R 資料框。
可以透過呼叫 sqlQuery
將 SQL 查詢傳送至資料庫。這會在 R 資料框中傳回結果。(sqlCopy
會將查詢傳送至資料庫,並將結果儲存為資料庫中的表格。)更精細的控制層級是先呼叫 odbcQuery
,然後呼叫 sqlGetResults
來擷取結果。後者可以在迴圈中使用,以一次擷取有限數量的列,函式 sqlFetchMore
也能這樣做。
以下是使用 PostgreSQL 的範例,其 ODBC 驅動程式會將欄位和資料框名稱對應至小寫。我們使用先前建立的資料庫 testdb
,並在 ~/.odbc.ini 的 unixODBC
下設定 DSN(資料來源名稱)。完全相同的程式碼使用 MyODBC 存取 Linux 或 Windows 下的 MySQL 資料庫(MySQL 也會將名稱對應至小寫)。在 Windows 下,DSN 會在控制台的 ODBC 小應用程式中設定(「管理工具」區段中的「資料來源 (ODBC)」)。
> library(RODBC) ## tell it to map names to l/case > channel <- odbcConnect("testdb", uid="ripley", case="tolower") ## load a data frame into the database > data(USArrests) > sqlSave(channel, USArrests, rownames = "state", addPK = TRUE) > rm(USArrests) ## list the tables in the database > sqlTables(channel) TABLE_QUALIFIER TABLE_OWNER TABLE_NAME TABLE_TYPE REMARKS 1 usarrests TABLE ## list it > sqlFetch(channel, "USArrests", rownames = "state") murder assault urbanpop rape Alabama 13.2 236 58 21.2 Alaska 10.0 263 48 44.5 ... ## an SQL query, originally on one line > sqlQuery(channel, "select state, murder from USArrests where rape > 30 order by murder") state murder 1 Colorado 7.9 2 Arizona 8.1 3 California 9.0 4 Alaska 10.0 5 New Mexico 11.4 6 Michigan 12.1 7 Nevada 12.2 8 Florida 15.4 ## remove the table > sqlDrop(channel, "USArrests") ## close the connection > odbcClose(channel)
作為在 Windows 下使用 ODBC 搭配 Excel 試算表的簡單範例,我們可以透過以下方式從試算表讀取
> library(RODBC) > channel <- odbcConnectExcel("bdr.xls") ## list the spreadsheets > sqlTables(channel) TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS 1 C:\\bdr NA Sheet1$ SYSTEM TABLE NA 2 C:\\bdr NA Sheet2$ SYSTEM TABLE NA 3 C:\\bdr NA Sheet3$ SYSTEM TABLE NA 4 C:\\bdr NA Sheet1$Print_Area TABLE NA ## retrieve the contents of sheet 1, by either of > sh1 <- sqlFetch(channel, "Sheet1") > sh1 <- sqlQuery(channel, "select * from [Sheet1$]")
請注意,表格的規格與 sqlTables
回傳的名稱不同:sqlFetch
能夠對應這些差異。
二進位連線(連線)現已成為處理二進位檔案的首選方式。
套件 h5、Bioconductor 的 rhdf5、RNetCDF 和 ncdf4 在 CRAN 上提供介面,可連線到 NASA 的 HDF5(階層式資料格式,請參閱 https://www.hdfgroup.org/HDF5/)和 UCAR 的 netCDF 資料檔案(網路通用資料格式,請參閱 https://www.unidata.ucar.edu/software/netcdf/)。
這兩個系統都是以陣列為導向的方式儲存科學資料,包括描述、標籤、格式、單位等。HDF5 也允許陣列的 群組,而 R 介面會將清單對應到 HDF5 群組,並可以寫入數字和字元向量及矩陣。
NetCDF 的版本 4 格式(令人困惑的是,在 netCDF 4.1.1 及後續版本中實作,但不在 4.0.1 中)包含使用各種 HDF5 格式。這由套件 ncdf4 處理,而 RNetCDF 處理版本 3 檔案。
支援這些格式的軟體可用性在不同平台上有些許限制,特別是在 Windows 上。
dBase
是由 Ashton-Tate 編寫的 DOS 程式,後來由 Borland 擁有,它有一個二進制平面檔案格式,變得流行,檔案副檔名為 .dbf。它已被採用於「Xbase」資料庫系列,涵蓋 dBase、Clipper、FoxPro 及其 Windows 等效版本 Visual dBase、Visual Objects 和 Visual FoxPro(請參閱 https://www.clicketyclick.dk/databases/xbase/format/)。dBase 檔案包含標頭,然後是一系列欄位,因此最類似於 R 資料框。資料本身以文字格式儲存,可以包含字元、邏輯和數字欄位,以及後續版本中的其他類型(例如,請參閱 https://www.loc.gov/preservation/digital/formats/fdd/fdd000325.shtml 和 https://www.clicketyclick.dk/databases/xbase/format/index.html)。
函式 read.dbf
和 write.dbf
提供方法,可以在所有 R 平台上讀取和寫入基本 DBF 檔案。對於 Windows 使用者,套件 RODBC 中的 odbcConnectDbase
提供更全面的功能,可透過 Microsoft 的 dBase ODBC 驅動程式讀取 DBF 檔案(也可以透過 odbcDriverConnect
使用 Visual FoxPro 驅動程式)。
二進位檔案中的一個特定類別是代表影像的檔案,而一個並不少見的要求是將此類檔案讀入 R 中作為矩陣。
影像檔案有許多格式(大多有許多變體),可能需要使用外部轉換軟體,先將影像轉換成目前套件提供 R 讀取器的其中一種格式。此類軟體的一個通用範例是 ImageMagick 及其分支 GraphicsMagick。這些提供命令列程式 convert
和 gm convert
,以將影像從一種格式轉換成另一種格式:它們可以輸入哪些格式是在編譯時決定的,而支援的格式可以透過例如 convert -list format
列出。
套件 pixmap 有函式 read.pnm
,以讀取 PBM(黑白)、PGM(灰階)和 PPM(RGB 色彩)格式的「可攜式任何地圖」影像。這些也稱為「netpbm」格式。
套件 bmp、jpeg 和 png 讀取以它們命名的格式。另請參閱套件 biOps 和 Momocs,以及 Bioconductor 套件 EBImage。
TIFF 較像是一種元格式,一個包裝器,其中可以嵌入各種影像格式。套件 rtiff 和 tiff 可以讀取一些子格式(視其編譯所依據的外部 libtiff
軟體而定)。有些特殊子格式有專門的工具,例如 Bioconductor 套件 beadarray。
光柵檔案在地理科學中很常見,而套件 rgdal 提供一個 GDAL 介面,GDAL 本身提供一些工具來讀取光柵檔案並連結到許多其他工具。它支援哪些格式是在編譯 GDAL 時決定的:使用 gdalDrivers()
來查看您正在使用的建置支援哪些格式。這對於一些不常見的格式很有用,例如 JPEG 2000(這是一種不同於 JPEG 的格式,目前 macOS 和 Windows 的 rgdal 二進位版本不支援)。
連線在 R 中的使用方式如同 Chambers (1998) 和 Ripley (2001) 所述,是一組函式,用於取代檔案名稱,以靈活的介面來存取類檔案物件。
最常見的連線類型是檔案,檔案連線是由函式 file
建立。檔案連線可以(如果作業系統允許特定檔案)以文字或二進位模式開啟用於讀取、寫入或附加。事實上,檔案可以同時開啟用於讀取和寫入,R 會分別為讀取和寫入保留獨立的檔案位置。
請注意,預設情況下,連線在建立時不會開啟。規則是,使用連線的函式應在連線尚未開啟時開啟連線(必要),並在使用後關閉連線(如果已開啟)。簡而言之,將連線保留在您找到它的狀態。有通用函式 open
和 close
,其方法可明確開啟和關閉連線。
使用 gzip
演算法壓縮的檔案可以用函式 gzfile
建立的連線,而使用 bzip2
壓縮的檔案可以用 bzfile
使用。
Unix 程式設計師習慣處理特殊檔案 stdin
、stdout
和 stderr
。這些存在於 R 中作為終端機連線。它們可能是普通檔案,但它們也可能參考 GUI 主控台的輸入和輸出。(即使使用標準 Unix R 介面,stdin
也會參考從 readline
提交的行,而不是檔案。)
三個終端連線始終處於開啟狀態,且無法開啟或關閉。stdout
和 stderr
通常分別用於一般輸出和錯誤訊息。它們通常會導向同一個地方,但一般輸出可以透過呼叫 sink
重新導向,而錯誤輸出會傳送至 stderr
,除非透過 sink, type="message")
重新導向。請仔細注意這裡使用的語言:連線無法重新導向,但輸出可以傳送至其他連線。
文字連線 是另一個輸入來源。它們允許 R 字元向量讀取,彷彿這些列是從文字檔讀取的。文字連線會透過呼叫 textConnection
建立並開啟,這會在建立時將字元向量的目前內容複製到內部緩衝區。
文字連線也可以用來擷取 R 輸出到字元向量。textConnection
可以要求建立新的字元物件或附加到現有的字元物件,這兩種情況都在使用者的工作區中。連線會透過呼叫 textConnection
開啟,而輸出至連線的完整列會隨時在 R 物件中提供。關閉連線會將任何剩餘輸出寫入字元向量的最後一個元素。
管道是一種連接到其他程序的特殊檔案形式,而管道連線是由函式 pipe
建立的。開啟一個管道連線以供寫入(將資料附加到管道中沒有意義)會執行一個作業系統指令,並將其標準輸入連接到 R 接著寫入該連線的任何內容。相反地,開啟一個管道連線以供輸入會執行一個作業系統指令,並讓其標準輸出可供 R 從該連線輸入。
URL 類型的「http://」、「https://」、「ftp://」和「file://」可以使用函式 url
讀取。為了方便起見,file
也會接受這些作為檔案規格,並呼叫 url
。
在支援類 Berkeley 資訊插座的平台(大多數 Unix 系統、Linux 和 Windows)上,資訊插座也可以透過函式 socketConnection
作為連線使用。資訊插座可以寫入或讀取,且可以使用用戶端和伺服器資訊插座。
我們已經描述了函式 cat
、write
、write.table
和 sink
作為寫入檔案,如果參數 append = TRUE
,則可能會附加到檔案,而這正是它們在 R 版本 1.2.0 之前所做的。
目前的行為是等效的,但實際上發生的是,當 file
參數為字元串時,會開啟一個檔案連線(用於寫入或附加),並在函式呼叫結束時再次關閉。如果我們想要重複寫入同一個檔案,更有效率的做法是明確宣告並開啟連線,並將連線物件傳遞給每個輸出函式的呼叫。這也讓寫入管線成為可能,這在較早之前透過語法 file = "|cmd"
(仍可使用)以有限的方式實作。
有一個函式 writeLines
可將完整的文字行寫入連線。
一些簡單的範例是
zz <- file("ex.data", "w") # open an output file connection cat("TITLE extra line", "2 3 5 7", "", "11 13 17", file = zz, sep = "\n") cat("One more line\n", file = zz) close(zz) ## convert decimal point to comma in output, using a pipe (Unix) ## both R strings and (probably) the shell need \ doubled zz <- pipe(paste("sed s/\\\\./,/ >", "outfile"), "w") cat(format(round(rnorm(100), 4)), sep = "\n", file = zz) close(zz) ## now look at the output file: file.show("outfile", delete.file = TRUE) ## capture R output: use examples from help(lm) zz <- textConnection("ex.lm.out", "w") sink(zz) example(lm, prompt.echo = "> ") sink() close(zz) ## now ‘ex.lm.out’ contains the output for futher processing. ## Look at it by, e.g., cat(ex.lm.out, sep = "\n")
從連線讀取的基本函式為 scan
和 readLines
。這些函式會取得一個字元串參數,並在函式呼叫期間開啟一個檔案連線,但明確開啟一個檔案連線允許以不同的格式循序讀取一個檔案。
其他呼叫 scan
的函式也可以使用連線,特別是 read.table
。
一些簡單的範例是
## read in file created in last examples readLines("ex.data") unlink("ex.data") ## read listing of current directory (Unix) readLines(pipe("ls -1")) # remove trailing commas from an input file. # Suppose we are given a file ‘data’ containing 450, 390, 467, 654, 30, 542, 334, 432, 421, 357, 497, 493, 550, 549, 467, 575, 578, 342, 446, 547, 534, 495, 979, 479 # Then read this by scan(pipe("sed -e s/,$// data"), sep=",")
為了方便起見,如果 file
參數指定一個 FTP、HTTP 或 HTTPS URL,URL 會透過 url
開啟以進行讀取。也可以透過『file://foo.bar』指定檔案。
C 程式設計師可能熟悉 ungetc
函數,用於將字元推回文字輸入串流。R 連線以更強大的方式具備相同概念,也就是說,透過呼叫 pushBack
,可以將(基本上)任意數量的文字行推回連線。
回推操作為堆疊,因此讀取要求會先使用最近回推文字的每一行,然後使用較早回推的文字,最後從連線本身讀取。一旦回推行完全讀取,就會清除該行。可透過呼叫 pushBackLength
找出已推回的待處理行數。
一個簡單的範例將說明這個概念。
> zz <- textConnection(LETTERS) > readLines(zz, 2) [1] "A" "B" > scan(zz, "", 4) Read 4 items [1] "C" "D" "E" "F" > pushBack(c("aa", "bb"), zz) > scan(zz, "", 4) Read 4 items [1] "aa" "bb" "G" "H" > close(zz)
回推僅適用於以文字模式開啟輸入的連線。
使用者目前開啟的所有連線摘要可透過 showConnections()
找到,而所有連線(包括已關閉和終端機連線)的摘要可透過 showConnections(all = TRUE)
找到。
通用函數 seek
可用於讀取並(在某些連線)重設目前位置,以進行讀取或寫入。不幸的是,這取決於可能不可靠的操作系統功能(例如 Windows 下的文字檔案)。函數 isSeekable
會報告 seek
是否可以變更其引數所提供的連線位置。
函數 truncate
可用於截斷在目前位置開啟可寫入的檔案。它僅適用於 file
連線,且並非在所有平台上皆有實作。
函數 readBin
和 writeBin
可讀取和寫入二進位連線。透過將 "b"
附加至模式規格,即可在二進位模式中開啟連線,也就是使用模式 "rb"
進行讀取,以及模式 "wb"
或 "ab"
(視情況而定)進行寫入。這些函數具有下列參數
readBin(con, what, n = 1, size = NA, endian = .Platform$endian) writeBin(object, con, size = NA, endian = .Platform$endian)
在每種情況下,con
都是一個連線,在呼叫期間需要開啟,如果給定字元串,則假設它指定一個檔名。
描述寫入會稍微簡單一些,因此我們將先這麼做。 object
應為原子向量物件,也就是模式為 numeric
、integer
、logical
、character
、complex
或 raw
的向量,且沒有屬性。預設情況下,這會以位元組串流的形式寫入檔案,其表示方式與在記憶體中的完全相同。
readBin
會從檔案讀取位元組串流,並將其解譯為由 what
給定的模式向量。這可以是適當模式的物件(例如 what=integer()
)或描述模式的字元串(前一段落中給定的五個字元串之一,或 "double"
或 "int"
)。參數 n
指定從連線讀取的向量元素最大數量:如果可用的數量較少,則會傳回較短的向量。參數 signed
允許將 1 位元組和 2 位元組整數讀取為有號(預設)或無號整數。
其餘兩個參數用於寫入或讀取資料,以便與其他程式或其他平台交換。預設會將二進位資料直接從記憶體傳輸到連線,或反之亦然。如果資料要傳輸到架構不同的機器,這是不夠的,但在幾乎所有 R 平台之間,唯一需要的變更就是位元組順序。常見的個人電腦(基於「ix86」和「x86_64」的機器)、康柏 Alpha 和 Vaxen 是小端序,而 Sun Sparc、mc680x0 系列、IBM R6000、SGI 和大多數其他機器則是大端序。(網路位元組順序(XDR,外部資料表示法所使用)是大端序。)要傳輸到或從其他程式,我們可能需要執行更多動作,例如讀取 16 位元整數或寫入單精度實數。這可以使用size
參數來完成,它(通常)允許整數和邏輯值的尺寸為 1、2、4、8,以及實數的尺寸為 4、8,或許還有 12 或 16。以不同的尺寸傳輸可能會失去精度,且不應嘗試對包含NA
的向量進行傳輸。
字元字串會以 C 格式讀取和寫入,也就是以一個以零位元組終止的位元組字串為格式。函數readChar
和writeChar
提供更大的彈性。
函數readBin
和writeBin
會傳遞遺失值和特殊值,儘管如果涉及尺寸變更,不應嘗試這麼做。
R 邏輯和整數類型的遺失值為 INT_MIN
,這是 C 標頭檔 limits.h 中定義的最小的可表示 int
,通常對應於位元模式 0x80000000
。
R 數值和複雜類型特殊值的表示法取決於機器,也可能取決於編譯器。使用它們最簡單的方法是連結外部應用程式到獨立的 Rmath
函式庫,它會匯出雙精度常數 NA_REAL
、R_PosInf
和 R_NegInf
,並包含定義巨集 ISNAN
和 R_FINITE
的標頭檔 Rmath.h。
如果這不可行,在所有目前的平台上都會使用 IEC 60559 (又稱 IEEE 754) 算術,因此可以使用標準 C 設施來測試或設定 Inf
、-Inf
和 NaN
值。在這些平台上,NA
會以低字元為 0x7a2
(十進位 1954) 的 NaN
值表示。
字元遺失值會寫成 NA
,而且沒有規定將字元值辨識為遺失值 (因為這可以在讀取後重新指派來完成)。
有些有限的設施可用於透過網路連線在較低層級交換資料。
基礎 R 提供一些功能,讓使用者可以在支援的系統上使用 via BSD socket 進行通訊(包括 R 常見的 Linux、Unix 和 Windows 埠)。使用 socket 的一個潛在問題是,這些功能通常會因為安全性考量或強制使用網路快取而遭到封鎖,因此這些功能在內部網路比在外部網路更實用。建議在新的專案中使用 socket 連線。
較早期的低階介面由函式 make.socket
、read.socket
、write.socket
和 close.socket
提供。
download.file
¶函式 download.file
可用來透過 FTP 或 HTTP(包括 HTTPS)從網路資源讀取檔案,並將其寫入檔案。通常可以避免這種情況,因為 read.table
和 scan
等函式可以直接從 URL 讀取,方法是明確使用 url
開啟連線,或隱含使用它,方法是將 URL 指定為 file
參數。
R 資料匯入/匯出最常見的問題似乎是「如何讀取 Excel 試算表」。本章節彙整之前提供的建議和選項。請注意,大部分建議適用於 Excel 2007 之前的試算表,而非後來的 .xlsx 格式。
第一個建議是盡量避免這麼做!如果您有 Excel,請從 Excel 中以 tab 分隔或逗號分隔的形式匯出您要的資料,並使用 read.delim
或 read.csv
將其匯入 R。(您可能需要在使用逗號作為小數點的區域設定中使用 read.delim2
或 read.csv2
。)匯出 DIF 檔案並使用 read.DIF
讀取是另一種可能性。
如果您沒有 Excel,許多其他程式可以在 Windows 和 Unix 上讀取此類試算表並以文字格式匯出,例如 Gnumeric (http://www.gnumeric.org) 和 OpenOffice (https://www.openoffice.org)。您也可以在這些程式中試算表的顯示畫面和 R 之間進行剪貼:read.table
會從 R 主控台讀取,或在 Windows 中從剪貼簿讀取(透過 file = "clipboard"
或 readClipboard
)。read.DIF
函數也可以從剪貼簿讀取。
請注意,Excel .xls 檔案不只是試算表:此類檔案可以包含許多工作表,而工作表可以包含公式、巨集等等。並非所有讀取器都能讀取第一個工作表以外的工作表,而且可能會因為檔案的其他內容而感到困惑。
Windows 使用者(32 位元 R)可以使用套件 RODBC 中的 odbcConnectExcel
。這可以從 Excel 試算表檔案(至少從 Excel 97–2003 開始,視您的 ODBC 驅動程式而定:直接呼叫 odbcConnect
可以讀取回溯至 Excel 3.0 的版本)中的任何工作表選取列和欄。版本 odbcConnectExcel2007
將讀取 Excel 2007 格式以及較早的格式(只要已安裝驅動程式,包括 64 位元 Windows R:請參閱 套件 RODBC)。macOS 使用者也可以使用 RODBC,只要他們有合適的驅動程式(例如 Actual Technologies 的驅動程式)。
Perl
使用者已貢獻一個模組 OLE::SpreadSheet::ParseExcel
和一個程式 xls2csv.pl
,用於將 Excel 95–2003 試算表轉換為 CSV 檔案。套件 gdata 在其 read.xls
函式中提供基本包裝器。只要安裝合適的 Perl
模組,這個函式也可以讀取 Excel 2007 試算表。
套件 dataframes2xls 和 WriteXLS 各包含一個函式,用於將一個或多個資料框寫入.xls檔案,分別使用 Python 和 Perl。
套件 xlsx 可以讀取和處理 Excel 2007 和更新的試算表:它需要 Java。
套件 XLConnect 可使用 Java 讀取、寫入和操作 Excel 97–2003 和 Excel 2007/10 試算表。
套件 readxl 可使用隨附的 C 函式庫讀取 Excel 97–2003 和 Excel 2007/10 試算表。
R. A. Becker、J. M. Chambers 和 A. R. Wilks(1988 年)The New S Language. A Programming Environment for Data Analysis and Graphics. Wadsworth & Brooks/Cole。
J. Bowman、S. Emberson 和 M. Darnovsky(1996 年)The Practical SQL Handbook. Using Structured Query Language. Addison-Wesley。
J. M. Chambers(1998 年)Programming with Data. A Guide to the S Language. Springer-Verlag。
P. Dubois(2000 年)MySQL. New Riders。
M. Henning 和 S. Vinoski(1999 年)Advanced CORBA Programming with C++. Addison-Wesley。
K. Kline 和 D. Kline(2001 年)SQL in a Nutshell. O’Reilly。
B. Momjian(2000 年)PostgreSQL: Introduction and Concepts. Addison-Wesley。也可在 https://momjian.us/main/writings/pgsql/aw_pgsql_book/ 取得。
B. D. Ripley(2001 年)Connections。 R News,1/1,16–7。 https://www.r-project.org/doc/Rnews/Rnews_2001-1.pdf
T. M. Therneau 和 P. M. Grambsch(2000 年)Modeling Survival Data. Extending the Cox Model. Springer-Verlag。
E. J. Yarger、G. Reese 和 T. King (1999) MySQL & mSQL。O’Reilly。
跳至: | .
B C D F G H I M N O P R S T U W X |
---|
跳至: | .
B C D F G H I M N O P R S T U W X |
---|
跳至: | A B C D E F H I L M N O P Q R S T U X Y |
---|
跳至: | A B C D E F H I L M N O P Q R S T U X Y |
---|
差異很細微,https://en.wikipedia.org/wiki/UTF-16/UCS-2,而且代理對的用量非常少。
即使如此,Windows 應用程式可能會預期位元組順序標記,R 使用的 iconv
實作可能會或可能不會根據平台加上這個標記。
這通常很快,因為查看第一個項目就能排除大部分可能性。
以及分支,特別是 MariaDB。