R 數(shù)據(jù)處理(四)

前言

前面講過了 R 自帶的讀取矩陣型數(shù)據(jù)的方法,如 read.csv,read.table 等挽绩。

下面我要介紹的是 tidyverse 中的 readr 包提供的讀取矩陣型數(shù)據(jù)的方式

readr 的目標(biāo)是提供一種快速友好的方式來讀取矩陣型數(shù)據(jù)生逸,如 csv, tsvfwf 等。

使用

1. 導(dǎo)入包

library(tidyverse)

函數(shù)

readr 支持 7 種文件格式,對(duì)應(yīng)于 7 個(gè) read_ 開頭的函數(shù)

    1. read_csv(): CSV 文件
    1. read_csv2(): 分號(hào) ; 分隔文件
    1. read_tsv(): tab 分隔文件
    1. read_delim(): 一般帶分隔符的文件
    1. read_fwf(): 固定寬度的文件
    1. read_table(): 表格文件榔昔,列之間用空格隔開
    1. 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)整這種模式:

  1. 當(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
  1. 有時(shí)珠洗,你的數(shù)據(jù)并沒有表頭,你可以使用 col_names = FALSE 告訴 read_csv() 不要把第一行作為表頭若专,然后用 X1Xn 依次標(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í)

  1. 使用什么函數(shù)讀取 | 分隔的文件主卫?

  2. 除了 fileskipcomment 之外鹃愤,read_csv()read_tsv() 還有哪些共同的參數(shù)簇搅?

  3. read_fwf() 最重要的參數(shù)是什么?

  4. 有時(shí) CSV 文件中的字符串包含 , 符號(hào)软吐。為了避免這種問題瘩将,它們需要被一個(gè)引號(hào)括起來,比如 "'凹耙。

    默認(rèn)情況下 read_csv() 假設(shè)字符被 " 包裹姿现,如何讀取下面的文本?

"x,y\n1,'a,b'"
  1. 確定下列每個(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, integerdate

> 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è)特別重要的解析器

  1. parse_logical()parse_integer() 分別解析邏輯和整數(shù)值

  2. parse_double() 是嚴(yán)格的數(shù)字解析器吨灭,parse_number() 是靈活的數(shù)字解析器刚照。這些并不是你想得那么容易,因?yàn)槭澜缟喜煌胤降臄?shù)字書寫方式不同喧兄。

  3. parse_character() 解析字符串

  4. parse_factor() 創(chuàng)建因子

  5. parse_datetime(), parse_date(), 和 parse_time() 可以解析各種時(shí)間和日期格式无畔。

下面將詳細(xì)介紹啊楚,

哦不!明天再說,脖子要斷了浑彰。

/(ㄒoㄒ)/~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恭理,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子郭变,更是在濱河造成了極大的恐慌颜价,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诉濒,死亡現(xiàn)場(chǎng)離奇詭異周伦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)未荒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門专挪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人片排,你說我怎么就攤上這事寨腔。” “怎么了划纽?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵脆侮,是天一觀的道長。 經(jīng)常有香客問我勇劣,道長靖避,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任比默,我火速辦了婚禮幻捏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘命咐。我一直安慰自己篡九,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布醋奠。 她就那樣靜靜地躺著榛臼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窜司。 梳的紋絲不亂的頭發(fā)上沛善,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音塞祈,去河邊找鬼金刁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尤蛮。 我是一名探鬼主播媳友,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼产捞!你這毒婦竟也來了醇锚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤轧葛,失蹤者是張志新(化名)和其女友劉穎搂抒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尿扯,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡求晶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衷笋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芳杏。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辟宗,靈堂內(nèi)的尸體忽然破棺而出爵赵,到底是詐尸還是另有隱情,我是刑警寧澤泊脐,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布空幻,位于F島的核電站,受9級(jí)特大地震影響容客,放射性物質(zhì)發(fā)生泄漏秕铛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一缩挑、第九天 我趴在偏房一處隱蔽的房頂上張望但两。 院中可真熱鬧,春花似錦供置、人聲如沸谨湘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽紧阔。三九已至,卻和暖如春续担,著一層夾襖步出監(jiān)牢的瞬間擅耽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國打工赤拒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秫筏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓挎挖,卻偏偏與公主長得像这敬,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蕉朵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容