前言
前面講過了 R
自帶的讀取矩陣型數(shù)據(jù)的方法,如 read.csv
,read.table
等挽绩。
下面我要介紹的是 tidyverse
中的 readr
包提供的讀取矩陣型數(shù)據(jù)的方式
readr
的目標(biāo)是提供一種快速友好的方式來讀取矩陣型數(shù)據(jù)生逸,如 csv
, tsv
和 fwf
等。
使用
1. 導(dǎo)入包
library(tidyverse)
函數(shù)
readr
支持 7
種文件格式,對(duì)應(yīng)于 7
個(gè) read_
開頭的函數(shù)
-
read_csv()
:CSV
文件
-
-
read_csv2()
: 分號(hào);
分隔文件
-
-
read_tsv()
:tab
分隔文件
-
-
read_delim()
: 一般帶分隔符的文件
-
-
read_fwf()
: 固定寬度的文件
-
-
read_table()
: 表格文件榔昔,列之間用空格隔開
-
-
read_log()
:web
日志文件
-
通常只要提供文件的路徑就可以讀取文件,比如讀取示例文件
> mtcars <- read_csv(readr_example("mtcars.csv"))
─ Column specification ────────────────────────────────────────
cols(
mpg = col_double(),
cyl = col_double(),
disp = col_double(),
hp = col_double(),
drat = col_double(),
wt = col_double(),
qsec = col_double(),
vs = col_double(),
am = col_double(),
gear = col_double(),
carb = col_double()
)
當(dāng)你使用 read_csv
時(shí)瘪菌,將會(huì)打印每列的列名以及類型撒会,函數(shù)自動(dòng)推斷數(shù)據(jù)的類型
當(dāng)然在讀取文件時(shí),你也可以為每列指定類型
mtcars <- read_csv(readr_example("mtcars.csv"), col_types =
cols(
mpg = col_double(),
cyl = col_integer(),
disp = col_double(),
hp = col_integer(),
drat = col_double(),
vs = col_integer(),
wt = col_double(),
qsec = col_double(),
am = col_integer(),
gear = col_integer(),
carb = col_integer()
)
)
你也可以提供一個(gè)內(nèi)聯(lián)的 CSV
文件
read_csv("a,b,c
1,2,3
4,5,6")
在這兩種讀取方式中控嗜,都是默認(rèn)將第一行作為列名茧彤。當(dāng)然,你也可以調(diào)整這種模式:
-
當(dāng)你的文件前幾行是數(shù)據(jù)的描繪信息疆栏,并不是你想要的曾掂,你可以使用
skip = n
跳過前n
行。或者壁顶,使用
comment = "#"
刪除所有以#
開頭的行
> read_csv("The first line of metadata
+ The second line of metadata
+ x,y,z
+ 1,2,3", skip = 2)
# A tibble: 1 x 3
x y z
<dbl> <dbl> <dbl>
1 1 2 3
> read_csv("# A comment I want to skip
+ x,y,z
+ 1,2,3", comment = "#")
# A tibble: 1 x 3
x y z
<dbl> <dbl> <dbl>
1 1 2 3
- 有時(shí)珠洗,你的數(shù)據(jù)并沒有表頭,你可以使用
col_names = FALSE
告訴read_csv()
不要把第一行作為表頭若专,然后用X1
到Xn
依次標(biāo)注
> read_csv("1,2,3\n4,5,6", col_names = FALSE)
# A tibble: 2 x 3
X1 X2 X3
<dbl> <dbl> <dbl>
1 1 2 3
2 4 5 6
此外许蓖,你還可以使用 col_names
參數(shù)設(shè)置列名
read_csv("1,2,3\n4,5,6", col_names = c("x", "y", "z"))
# A tibble: 2 x 3
x y z
<dbl> <dbl> <dbl>
1 1 2 3
2 4 5 6
另一個(gè)需要調(diào)整的選項(xiàng)是 na
,用來標(biāo)識(shí)缺省的值
read_csv("a,b,c\n1,2,.", na = ".")
# A tibble: 1 x 3
a b c
<dbl> <dbl> <lgl>
1 1 2 NA
對(duì)于 read_tsv()
和 read_fwf()
的讀取方式调衰,也是類似的膊爪,就不再做詳細(xì)介紹了。
如果想要進(jìn)一步了解讀取方式嚎莉,那就要知道 readr
是如何解析每一列米酬,并如何轉(zhuǎn)換為 R
向量的。
與 R 基礎(chǔ)操作對(duì)比
你可能會(huì)問趋箩,為什么我不直接用 R
自帶的 read.csv
或其他類似的 read.table
等函數(shù)來讀取文件呢赃额?
其原因是:
首先,通常它的讀取速度比
R
基礎(chǔ)函數(shù)快很多(大約10
倍)叫确。在長時(shí)間的運(yùn)行過程中跳芳,會(huì)有一個(gè)進(jìn)度條,讓你知道程序運(yùn)行到哪里了竹勉。如果你對(duì)速度的追求更高飞盆,可以嘗試data.table::fread()
函數(shù),但是它沒有readr
的兼容性好其次,它們產(chǎn)生的是
tibble
格式的數(shù)據(jù)桨啃,不會(huì)將字符串轉(zhuǎn)換為factor
车胡,使用行名或列名。最后照瘾,它們更容易復(fù)制匈棘,基礎(chǔ)的
R
函數(shù)是從你的操作系統(tǒng)和環(huán)境變量繼承了一些行為,因此在你的計(jì)算機(jī)上運(yùn)行的代碼可能無法在其他計(jì)算機(jī)上運(yùn)行析命。
思考練習(xí)
使用什么函數(shù)讀取
|
分隔的文件主卫?除了
file
、skip
和comment
之外鹃愤,read_csv()
和read_tsv()
還有哪些共同的參數(shù)簇搅?read_fwf()
最重要的參數(shù)是什么?-
有時(shí)
CSV
文件中的字符串包含,
符號(hào)软吐。為了避免這種問題瘩将,它們需要被一個(gè)引號(hào)括起來,比如"
或'
凹耙。默認(rèn)情況下
read_csv()
假設(shè)字符被"
包裹姿现,如何讀取下面的文本?
"x,y\n1,'a,b'"
- 確定下列每個(gè)內(nèi)聯(lián)
CSV
文件的錯(cuò)誤所在肖抱。運(yùn)行代碼時(shí)會(huì)發(fā)生什么备典?
read_csv("a,b\n1,2,3\n4,5,6")
read_csv("a,b,c\n1,2\n1,2,3,4")
read_csv("a,b\n\"1")
read_csv("a,b\n1,2\na,b")
read_csv("a;b\n1;3")
解析向量
在深入了解 readr
如何從磁盤讀取文件之前,我們需要稍微討論一下 parse_*()
函數(shù)
這些函數(shù)接受一個(gè)字符向量并返回一個(gè)更專門的向量意述,如 logical
, integer
或 date
> str(parse_logical(c("TRUE", "FALSE", "NA")))
logi [1:3] TRUE FALSE NA
> str(parse_integer(c("1", "2", "3")))
int [1:3] 1 2 3
> str(parse_date(c("2010-01-01", "1979-10-14")))
Date[1:2], format: "2010-01-01" "1979-10-14"
這些函數(shù)本身很有用提佣,但也是 readr
的一個(gè)重要構(gòu)建部分。
在了解完本節(jié)中各個(gè)解析器的工作原理后荤崇,我們將在下一節(jié)中回過頭來看看它們是如何組合在一起解析完整的文件
和其他許多 tidyverse
函數(shù)一樣拌屏,parse_*()
函數(shù)也是統(tǒng)一的,第一個(gè)參數(shù)是要解析的字符向量术荤,而 na
參數(shù)指定哪些字符串應(yīng)該被視為缺失值
parse_integer(c("1", "231", ".", "456"), na = ".")
[1] 1 231 NA 456
如果解析失敗倚喂,你會(huì)得到一個(gè)警告
> x <- parse_integer(c("123", "345", "abc", "123.45"))
Warning: 2 parsing failures.
row col expected actual
3 -- an integer abc
4 -- no trailing characters 123.45
但是錯(cuò)誤并不會(huì)包含在輸出中
> x
[1] 123 345 NA NA
attr(,"problems")
# A tibble: 2 x 4
row col expected actual
<int> <int> <chr> <chr>
1 3 NA an integer abc
2 4 NA no trailing characters 123.45
如果有許多解析失敗,你可以使用 problems()
來獲得完整的信息喜每。這會(huì)返回一個(gè) tibble
,然后您可以使用 dplyr
對(duì)其進(jìn)行操作雳攘。
> problems(x)
# A tibble: 2 x 4
row col expected actual
<int> <int> <chr> <chr>
1 3 NA an integer abc
2 4 NA no trailing characters 123.45
使用解析器主要是為了理解什么是可用的带兜,以及它們是如何處理不同類型的輸入。
總共有八個(gè)特別重要的解析器
parse_logical()
和parse_integer()
分別解析邏輯和整數(shù)值parse_double()
是嚴(yán)格的數(shù)字解析器吨灭,parse_number()
是靈活的數(shù)字解析器刚照。這些并不是你想得那么容易,因?yàn)槭澜缟喜煌胤降臄?shù)字書寫方式不同喧兄。parse_character()
解析字符串parse_factor()
創(chuàng)建因子parse_datetime()
,parse_date()
, 和parse_time()
可以解析各種時(shí)間和日期格式无畔。
下面將詳細(xì)介紹啊楚,
哦不!明天再說,脖子要斷了浑彰。
/(ㄒoㄒ)/~~