【tidyverse】part2:數(shù)據(jù)整理

1. tibble數(shù)據(jù)

1.1 tibble數(shù)據(jù)簡介

“Tibbles are data frames, but they tweak some older behaviors to make life a little easier.”
——Hadley Wickham《R for data science》

Tibble是數(shù)據(jù)框的一種形式尔苦,但是比數(shù)據(jù)框更整潔翎卓,結(jié)構(gòu)更加緊湊楔绞,可以理解為tidy table之意

  • 如果加載了tidyverse拉宗,統(tǒng)一采用tibble格式的數(shù)據(jù)集

1.2 tibble數(shù)據(jù)創(chuàng)建

可以通過tibble()函數(shù)來像data.frame()一樣來創(chuàng)建tibble數(shù)據(jù)

tibble(
    x = 1:5, 
    y = 1, 
    z = x ^ 2 + y
)

或者可以通過轉(zhuǎn)置函數(shù)as_tibble()來將data.frame格式的數(shù)據(jù)轉(zhuǎn)化為tibble格式的數(shù)據(jù)

as_tibble(mtcars)

  • 需要注意的是蓖乘,不同于傳統(tǒng)的R語言as.*一類函數(shù)的用法故觅,對于變量類型的轉(zhuǎn)換酝惧,使用的是parse_*函數(shù)族瞎饲,而對于數(shù)據(jù)集則使用的是as_*函數(shù)族
  • 并且轉(zhuǎn)化時沈善,tibble數(shù)據(jù)不會改變原始數(shù)據(jù)的任何信息

如果是想以表格的形式輸入數(shù)據(jù)乡数,可以使用tribble()函數(shù)來創(chuàng)建,只是與tibble()格式有點(diǎn)小小的不同:

tribble(
  ~x, ~y, ~z,
  #--/--/----
  'a', 2, 3.6,
  'b', 3, 2.5
)
  • 這種格式變量通常以「~」開頭
  • 使用注釋符號來分隔符會使得輸入能整潔且便于對應(yīng)表頭
  • 注意不要漏掉「,」半角逗號

1.3 tibble數(shù)據(jù)與傳統(tǒng)data.frame

tibble數(shù)據(jù)與data.frame數(shù)據(jù)相比主要在以下兩個方面有所不同:

  • 打印輸出
  • 子集索引

打印輸出

tibble數(shù)據(jù)輸出到console上只會顯示前10行闻牡,和所有列净赴;這對于大數(shù)據(jù)量而言是十分有益的

  • 如果想獲取更詳細(xì)的信息,使用str()函數(shù)來提取

如果想明確輸出具體的打印信息罩润,可以在print()函數(shù)中設(shè)置n=#width=Inf玖翅,分別對應(yīng)行和列的數(shù)量饭入;
當(dāng)然還可以設(shè)定默認(rèn)打印輸出的參數(shù),主要有以下三個選項(xiàng)可供修改:

# 最大最小打印值
options(tibble.print_max = m, 
        tibble.print_min = n)
        
# 輸出所有行
options(dplyr.print_min = Inf)

# 輸出所有列
options(tibble.width = Inf)
  • 如果想獲取更多可以使用package?tibble查看

子集索引

tibble索引與傳統(tǒng)data.frame格式索引一致迁沫,主要差別在:
tibble數(shù)據(jù)使用的是嚴(yán)謹(jǐn)?shù)娜科ヅ湮绻噲D索引一個不存在的列,其會生成警告

小結(jié)

  • tibble是data.frame的一種审姓,但結(jié)構(gòu)更緊湊珍特、簡潔
  • 創(chuàng)建tibble數(shù)據(jù)有tibble()tribble()兩個函數(shù),也可以通過as_tibble()來轉(zhuǎn)換
  • tibble與data.frame的區(qū)別在于輸出打印和子集索引上魔吐,并且R許多基礎(chǔ)的函數(shù)功能可能對與tibble數(shù)據(jù)并不起作用扎筒,因此如果需要用到某些函數(shù)功能時,可能需要將tibble數(shù)據(jù)轉(zhuǎn)換成data.frame格式

2. 數(shù)據(jù)整理之tidyr包應(yīng)用

2.1 什么是tidy數(shù)據(jù)

tidy數(shù)據(jù)表示的是已經(jīng)整理好的酬姆、整潔的數(shù)據(jù)嗜桌,通常現(xiàn)實(shí)中的數(shù)據(jù)許多都是混亂辞色,甚至是「臟」的骨宠,將這些數(shù)據(jù)進(jìn)行處理后所得到的數(shù)據(jù)就可以稱之為tidy數(shù)據(jù)

tidyverse包中的其他包都是為tidy數(shù)據(jù)而設(shè)計(jì)的;也可以說相满,tibble格式的數(shù)據(jù)就是tidy數(shù)據(jù)的表現(xiàn)形式层亿;通識tidy數(shù)據(jù)有以下三個方面的特征:

  • 每個變量都對應(yīng)著單獨(dú)的一列
  • 每條記錄都對應(yīng)著單獨(dú)的一行
  • 每個觀察值都對應(yīng)著單獨(dú)的單元格

2.2 數(shù)據(jù)預(yù)處理函數(shù)

2.2.1 分散與聚合

在現(xiàn)實(shí)的分析中,往往需要對數(shù)據(jù)進(jìn)行的初步處理立美,使數(shù)據(jù)變得整潔:

  1. 第一步是需要確定變量和觀察值是哪些
  2. 使確定好的變量和觀察值能夠分別很好地對應(yīng)列和行

spread函數(shù)

分散函數(shù)是將變量中的值拆分成新的變量匿又,這個過程概括為就是將為成「列」的值,進(jìn)行拆分建蹄,并指定其他列作為「值」碌更,組合成「鍵-值」對的形式

#spread函數(shù)語法
spread(data, key= , value=, )

#以table2數(shù)據(jù)集為例子
table2 #查看數(shù)據(jù)集
table2 %>% 
  spread(key = 'type', value = 'count')

type列的值拆分作為「鍵」,count列的值則作為每個鍵下的「值」洞慎,進(jìn)而將變量值進(jìn)行拆分

gather函數(shù)

在一些數(shù)據(jù)中存在的問題是痛单,列名并非是變量名,反而是變量的某個具體值劲腿,因此就需要將這些已經(jīng)成為列的「值」聚合到一起桦他,還原成其本來歸屬的變量里;聚合函數(shù)與分散函數(shù)是一對互逆的過程

#gather函數(shù)語法
gather(data, set_colums, key= , value=, ...)

# 以tidyverse包中的table4a數(shù)據(jù)為例
table4a #查看數(shù)據(jù)集
table4a %>% 
  gather(`1999`, `2000`, 
  key = 'year', value = 'cases')

簡而言之谆棱,gather函數(shù)就是將成為列的「值」進(jìn)行「鍵-值」形式的拆分:

  • 每個19992000都對應(yīng)著一個不同的值快压;
  • 因此根據(jù)gather函數(shù)中的keyvalue參數(shù)不難發(fā)現(xiàn),前者是為19992000指定新的「鍵」垃瞧,即變量蔫劣;而后者則為這些「值」指定新的變量

通過觀察可以很容易看出:

  • gather()函數(shù)是將數(shù)據(jù)寬格式數(shù)據(jù)轉(zhuǎn)化為長且窄的格式數(shù)據(jù),這對于ggplot2包的使用極其有用
  • spread()函數(shù)則是將長格式數(shù)據(jù)轉(zhuǎn)化為短且寬格式數(shù)據(jù)

2.2.2 拆分與黏合

分散與聚合是處理將變量與值進(jìn)行轉(zhuǎn)化時使用到的函數(shù)个从;而有時需要將一個列中的值拆分成兩個變量的值脉幢,或者將兩個變量的值組合成一個新的變量的值歪沃,這時候就需要使用到拆分與黏合函數(shù)

separate函數(shù)

#separate函數(shù)語法
separate(data, col, into= )

#以table3數(shù)據(jù)集為例子
table3 #查看數(shù)據(jù)集
table3 %>%
    separate(rate, into=c('cases','population'))
  • 從語法和例子上可以清楚的了解到separate參數(shù)的指定過程
  • 但是該函數(shù)默認(rèn)是將非字母和數(shù)字的字符進(jìn)行分隔,如果希望指定分隔符嫌松,則需要額外使用sep= ''參數(shù)
    • 如果是要將數(shù)字進(jìn)行分隔沪曙,那么使用sep參數(shù)時需要注意位數(shù)的正負(fù):

      • sep=1時,則是從左往右進(jìn)行位數(shù)拆分
      • sep=-1時萎羔,則是從右往左進(jìn)行位數(shù)拆分
  • 并且要注意拆分后變量的類型液走,有可能會并非正確的數(shù)據(jù)類型,因此需要在轉(zhuǎn)換時加上convert =T參數(shù)來確保變量轉(zhuǎn)換成正確的類型

unite函數(shù)

同分散與聚合一樣贾陷,拆分與黏合函數(shù)同樣時一對互逆的函數(shù)與過程缘眶;黏合函數(shù)是將兩列變量的值黏合到一起,組成新的變量

#unite函數(shù)語法
unite(data, new_col, old_cols)

#接著separate的例子
table3 %>%
    separate(year, into=c('century','year')) %>%
    unite(new_year, century, year)
  • unite()函數(shù)默認(rèn)使用「_」來聯(lián)結(jié)黏合的值髓废,可以通過sep參數(shù)來調(diào)整
  • 拆分與黏合的語法基本一致巷懈,不同的是在第二個參數(shù)的使用上

2.2.3 缺失值處理

缺失值的存在方式主要可能有兩種:

  1. 直接用NA來表明
  2. 間接的使用其他方式來呈現(xiàn):如應(yīng)該出現(xiàn)的卻沒有出現(xiàn)、NULL慌洪、stata中的「.」等顶燕,這些都有可能是缺失值

complete

complete()函數(shù)是將數(shù)據(jù)集中所有不重復(fù)的列組合到一起進(jìn)行展示,對于原始數(shù)據(jù)缺失的值用NA來進(jìn)行填充

#complete函數(shù)語法
complete(data, unique_cols,...)

fill

fill()函數(shù)通過名稱可以很容易得知冈爹,這是將缺失值進(jìn)行替換的函數(shù):

#設(shè)定數(shù)據(jù)集
treatment <- tribble( 
        ~ person,            ~ treatment, ~response, 
        #-----------------/------------/----------/
        "Derrick Whitmore",             1,         7, 
        NA,                             2,        10, 
        NA,                             3,         9, 
        "Katherine Burke",              1,         4
)

treatment %>% 
  fill(person)

fill()函數(shù)默認(rèn)是用NA值的前面一個值來覆蓋NA涌攻,如果想調(diào)整方向,可以使用.direction=c('up')參數(shù)來進(jìn)行調(diào)整

  • 如果忘記參數(shù)可以使用?fill查看幫助文檔

小結(jié)

  • 本小節(jié)主要設(shè)計(jì)三組對于數(shù)據(jù)預(yù)處理的函數(shù):分散與聚合犯助、拆分與黏合、缺失值展示與填充
  • 分散與聚合是將以「鍵-值」對的形式來展開轉(zhuǎn)化
  • 拆分與黏合是將單個值或多個變量拆分或黏合成一個或多個變量的過程
  • 缺失值的存在方式有直接和間接兩種

運(yùn)用案例

使用「who」數(shù)據(jù)集维咸,對數(shù)據(jù)集進(jìn)行整理并最后得到tidy數(shù)據(jù)

library(tidyverse)
who

查看數(shù)據(jù)集剂买,可以發(fā)現(xiàn):

  • iso2和iso3表示地名
  • year為變量,不需要變動
  • 其他一系列的函數(shù)同名較多癌蓖,可能為值瞬哼,需要進(jìn)行聚合
who %>%
    gather(new_sp_m014:newrel_f65, 
    key = "key", value = "cases", na.rm = TRUE)

對數(shù)據(jù)列進(jìn)行聚合,并且刪除缺失值

之后通過查看key變量的頻數(shù)可以發(fā)現(xiàn)每個取值都是有規(guī)律的租副,都是由「_」下劃線來分隔坐慰,因此只需要以「_」來分隔來決定是否對分隔后的變量保留即可;
但是有一點(diǎn)需要注意的是用僧,newrel的一系列值并沒有下劃線结胀,因此需要額外使用到stringr包中的str_replace來對這一系列值進(jìn)行分隔符添加,然后再進(jìn)行分隔

#str_replace函數(shù)語法
library(stringr)
str_replace(string, pattern, replacement)

#添加下劃線
who %>%
    mutate(key = stringr::str_replace(key, 'newrel', 'new_rel') %>%
    separate(key, c('new', 'type', 'sexage'), sep = '_')

最后需要再對sexage進(jìn)行拆分责循,然后刪除冗余的變量糟港,保留需要的變量即可


who %>%
    select(-iso2, -iso3, -new) %>%
    separate(sexage, c('sex', 'age'), sep = 1))
  • 注意sep=1是指定從左往右分隔1位數(shù)

完整代碼:

who %>% 
  gather(new_sp_m014:newrel_f65, 
         key = 'key', value = 'cases', na.rm = T) %>% 
  mutate(key = stringr::str_replace(key, 'newrel', 'new_rel')) %>% 
  separate(key, c('new', 'type', 'sexage'), sep = '_') %>% 
  select(-iso2, -iso3, -new) %>% 
  separate(sexage, c('sex', 'age'), sep = 1)

  • 使用到的stringr包的str_replace()函數(shù)以及select()mutate()函數(shù)為后面章節(jié)的函數(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市院仿,隨后出現(xiàn)的幾起案子秸抚,更是在濱河造成了極大的恐慌速和,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剥汤,死亡現(xiàn)場離奇詭異颠放,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吭敢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門碰凶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人省有,你說我怎么就攤上這事痒留。” “怎么了蠢沿?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵伸头,是天一觀的道長。 經(jīng)常有香客問我舷蟀,道長恤磷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任野宜,我火速辦了婚禮扫步,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匈子。我一直安慰自己河胎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布虎敦。 她就那樣靜靜地躺著游岳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪其徙。 梳的紋絲不亂的頭發(fā)上胚迫,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音唾那,去河邊找鬼访锻。 笑死,一個胖子當(dāng)著我的面吹牛闹获,可吹牛的內(nèi)容都是我干的期犬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼避诽,長吁一口氣:“原來是場噩夢啊……” “哼哭懈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茎用,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤遣总,失蹤者是張志新(化名)和其女友劉穎睬罗,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旭斥,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡容达,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了垂券。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片花盐。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖菇爪,靈堂內(nèi)的尸體忽然破棺而出算芯,到底是詐尸還是另有隱情,我是刑警寧澤凳宙,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布熙揍,位于F島的核電站,受9級特大地震影響氏涩,放射性物質(zhì)發(fā)生泄漏届囚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一是尖、第九天 我趴在偏房一處隱蔽的房頂上張望意系。 院中可真熱鬧,春花似錦饺汹、人聲如沸蛔添。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迎瞧。三九已至,卻和暖如春弦疮,著一層夾襖步出監(jiān)牢的瞬間夹攒,已是汗流浹背蜘醋。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工胁塞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人压语。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓啸罢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胎食。 傳聞我的和親對象是個殘疾皇子扰才,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

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