R 資料輸入與輸出

這裡介紹 R 資料輸入與輸出的基本技巧,包含 R 程式碼、文字資料的讀取與儲存,以及圖形檔案的輸出。

在使用 R 分析資料時,資料的來源是整個分析流程中不可缺少的環節,而分析的結果也常常需要輸出成文字報表,或是以圖形檔案的方式呈現,以下將介紹 R 中最基本的程式碼指令稿運用、資料讀取與儲存技巧,還有各種點陣圖與向量圖的輸出方式。

程式碼輸入與輸出

通常使用者以 R 撰寫程式碼時,都會將寫好的程式碼儲存在指令稿(.R 檔)檔案中,方便程式碼重複使用。若要從 R 中載入並執行指令稿中的程式碼,可以使用 source 指令,例如:

source("script.R")

source 預設在執行指令稿中的 R 程式碼時,除非遇到有呼叫 print 這類的輸出函數,否則不會有特別的輸出訊息,如果想要讓 R 在執行程式時,可以順便輸出執行的內容(就像自己複製與貼上程式碼一樣),可以加上 echo = TRUE 參數:

source("script.R", echo = TRUE)
> set.seed(1)

> (test.x <- runif(5))
[1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819

如果要將 R 中執行過的歷史指令儲存在檔案中,可以使用 savehistory 指令:

savehistory("my_history.R")

這樣就會將 R 的指令儲存成一般的 .R 指令稿,也就是說這個指令稿也可以使用 source 來執行。若要載入檔案中的歷史指令,可以使用 loadhistory 指令:

loadhistory("my_history.R")

R 內建資料

R 的 datasets 套件提供了大約 100 個內建的資料集,使用 data 函數可以列出所有可用的資料集:

data()

這些資料都可以透過其名稱直接取用:

head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

CSV 檔案輸入

csv 檔是一種以逗點分隔欄位的資料檔,大多數的應用程式都會支援這種檔案格式。

假設外部的 CSV 檔 data-1.csv 內容如下:

Price,Floor,Area,Rooms,Age,Cent.heat
52.00,111.0,830,5,6.2,no
54.75,128.0,710,5,7.5,no
57.50,131.0,690,6,8.8,no
59.75,93.0,900,5,1.9,yes

read.csv 函數可以讀取外部的 CSV 檔:

read.csv("data-1.csv")
  Price Floor Area Rooms Age Cent.heat
1 52.00   111  830     5 6.2        no
2 54.75   128  710     5 7.5        no
3 57.50   131  690     6 8.8        no
4 59.75    93  900     5 1.9       yes

sep 參數可指定分隔字元:

read.csv("data-tab-1.csv", sep = "\t")

read.csv 亦可接受 URL:

read.csv("http://www.your.host/data.csv")

文字檔案輸入

假設外部的文字檔 data-2.txt 內容如下:

31 2 3 9 32 342 34
33 34 23
234 29 29 73 63 56 32 36 98 32

scan 可以將檔案中的資料直接讀取進來,變成一個向量:

scan("data-2.txt")
Read 20 items
 [1]  31   2   3   9  32 342  34  33  34  23 234  29  29  73  63  56  32  36  98
[20]  32

如果文字檔案的內容比較複雜,有文字與數值參雜時,可以根據資料的格式自行定義樣板,讓 scan 依照樣板讀取資料。

假設文字檔 data-3.txt 每一筆資料包含一個字串與兩個數值:

John 2.4 33 Joe 3.2 12 Mary 9.2 11
Dan 6 23 Willy 3.9 33

使用 scan 配合樣板讀取資料:

scan("data-3.txt", list(name = "", val.a = 0, val.b = 0))
Read 5 records
$name
[1] "John"  "Joe"   "Mary"  "Dan"   "Willy"

$val.a
[1] 2.4 3.2 9.2 6.0 3.9

$val.b
[1] 33 12 11 23 33

假設文字檔 data-4.txt 都是一些字元,例如:

Mary Joe John
Willy Dan

則使用:

scan("data-4.txt", "")
Read 5 items
[1] "Mary"  "Joe"   "John"  "Willy" "Dan"

資料檔案輸出

如果想要讓程式的輸出訊息直接儲存至檔案,可以使用 sink 函數:

sink("sink-example.txt")
i <- 1:3
outer(i, i, "*")
sink()

輸出的 sink-example.txt 為:

     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    2    4    6
[3,]    3    6    9

save 函數可以將變數儲存於硬碟中:

x <- c(1.2, 3.4, 5.6)
y <- x ^ 2
save(x, y, file = "xy.RData")

load 函數則可將儲存的變數載入:

rm(list = ls())
load("xy.RData")
ls.str()
x :  num [1:3] 1.2 3.4 5.6
y :  num [1:3] 1.44 11.56 31.36

save 函數預設在儲存資料時會使用 gzip 壓縮格來儲存,如果要儲存的資料非常大,可以更改壓縮的演算法:

x.large <- runif(10^6)
object.size(x.large)
save(x.large, file = "compress.xz", compress = "xz")

以下是用各種壓縮格式所產生的檔案大小比較:

壓縮格式 壓縮檔大小
gzip(預設值) 5.3 MB
bzip2 4.8 MB
xz 4.4 MB

如果要儲存單一個變數,也可以使用 saveRDS 來將資料儲存為 rds 檔:

saveRDS(women, "women.rds")

若要從 rds 檔案中載入變數,可以使用 readRDS 函數:

women2 <- readRDS("women.rds")
identical(women, women2)

若要將 R 的 data frame 輸出為 csv 檔,可以使用 write.csv 函數:

write.csv(cars, file = "output-cars.csv")

write.table 函數的功能與 write.csv 類似,但可用 sep 指定分隔字元:

write.table(cars, file = "output-cars.csv", sep = "\t")

圖形檔案輸出

png 函數可以將圖形輸出為 png 點陣圖檔:

set.seed(5)
x <- rnorm(100)
png("output.png", width = 640, height = 360) # 設定輸出圖檔
hist(x) # 繪圖
dev.off() # 關閉輸出圖檔

輸出的圖形為:

r-data-input-and-output-20161105-1

圖形輸出

jpegtiffbmp 這些函數也可以將圖形輸出成各種不同的點陣圖檔,使用方式跟 png 函數都相同。

若要輸出向量圖,可以使用 pdf 或是 svg 函數:

pdf("output.pdf", width = 4, height = 3)
hist(x)
dev.off()

如果要將 R 所繪製的圖形放在 LaTeX 中使用,可以使用 postscript 指令輸出成適用於 LaTeX 環境的 eps 向量圖檔:

postscript("output.eps", width = 4.0, height = 3.0,
  horizontal = FALSE, onefile = FALSE, paper = "special",
  family = "ComputerModern", encoding = "TeXtext.enc")
hist(x)
dev.off()

如果使用 ggplot2 套件在指令稿中畫圖時,必須加上 print 才能使圖形檔案正常輸出:

pdf("output.pdf", width = 4, height = 3)
print(qplot(x))
dev.off()

ggplot2 本身也提供了一個 ggsave 圖形輸出函數,它可以在 R 互動式的操作模式中,將已經畫在螢幕上的圖形輸出為圖檔:

qplot(x)
ggsave("plot.pdf", width = 4, height = 3)

R

1 Comment

  1. konny

    GOOD

Leave a Reply