Learn R | 數據重塑之tidyr包

前言

之前我們詳細的學習了reshape2包,在數據處理階段,它幫助我們很容易的實現長寬格式數據之間的轉換。而今天所要學習的tidyr包可以看作是reshape2包的進化版本,該包的作者依舊是Rstudio的首席科學家,R語言界的大神Hadley Wickham。tidyr包往往與dplyr包結合使用,目前漸有取代reshape2包之勢, 是值得關注的一個R包。

在tidyr包中,有四個常用的函數,分別是:

  • gather():寬數據轉換為長數據,將行聚集成列
  • spread():長數據轉換為寬數據,將列展開為行

  • unite():多列合併為一列
  • separate():將一列分離為多列.

接下來我們主要對這四個函數進行詳細學習,並在此基礎上學習tidyr包其他的一些實用功能。

一、gather()函數

導入所用的包

> library(dplyr)n> library(tidyr)n

如前面所說,gather()函數是將寬數據轉換為長數據,調用公式如下:

> gather(data=,key=,value=,...,na.rm=,convert=,factor_key=)n# key:創建一個新的列名,原數據的舊列名成為新列名的觀測值n# value:再創建一個新的列名,原數據的所有舊列名的觀測值成為新列名的觀測值n# ...:按照實際需要自行指定需要轉換的列n# na.rm:邏輯值,是否刪除缺失值n# convert:邏輯值,在key列是否進行數據類型轉換n# factor_key:邏輯值,若是F,則key自動轉換為字元串,反之則是因子(原始lever水平保持不變)n

數據轉換的示意圖(來源:Data Processing with dplyr & tidyr):

首先我們先查看原始數據:

> head(iris,3)n Sepal.Length Sepal.Width Petal.Length Petal.Width Speciesn1 5.1 3.5 1.4 0.2 setosan2 4.9 3.0 1.4 0.2 setosan3 4.7 3.2 1.3 0.2 setosan

使用gather()函數進行數據重塑(代碼中%>%為管道函數,這也是我們為什麼要載入dplyr包的原因,關於管道函數,詳見R Language Learning:dplyr包(十一))

> iris %>%n+ gather(key=var1,value = var2,...=1:4,na.rm = F) %>%n+ arrange(desc(var2)) %>%n+ head(3)n Species var1 var2n1 virginica Sepal.Length 7.9n2 virginica Sepal.Length 7.7n3 virginica Sepal.Length 7.7n

二、spread()函數

spread()函數將長數據轉為寬數據,即將列展開為行,調用公式如下:

> spread(data = ,key = ,value = ,fill = ,convert = ,drop = )n# key:指定轉換的某列,其觀測值作為轉換後的列名n# value:其他列的觀測值分散到相對應的各個單元n# fill:設定某個值,替換缺失值n

我們使用R中的economics數據集來使用學習這一函數。

# 提取原數據集前三列n> data <- economics[1:3]n> head(data,3)n# A tibble: 3 × 3n date pce popn <date> <dbl> <int>n1 1967-07-01 507.4 198712n2 1967-08-01 510.5 198911n3 1967-09-01 516.3 199113n

# 由於手邊沒有合適的長數據,所以我們先使用gather函數生成一份新的長數據,並假定我們要對這一份長數據進行列轉行n> data %>%n+ gather(key=var1,value = var2,-date) %>%n+ head(3)n# A tibble: 3 × 3n date var1 var2n <date> <chr> <dbl>n1 1967-07-01 pce 507.4n2 1967-08-01 pce 510.5n3 1967-09-01 pce 516.3n# -date:默認數據集中的date不做變化n

# 使用spread()函數進行了長數據向寬數據的轉換n# 原有的var1變數作為轉換後的列名,var2變數值作為相應的觀測值分散到各列n> data %>%n+ gather(key = var1,value = var2,-date) %>%n+ spread(key = var1,value = var2) %>%n+ head(3)n# A tibble: 3 × 3n date pce popn <date> <dbl> <dbl>n1 1967-07-01 507.4 198712n2 1967-08-01 510.5 198911n3 1967-09-01 516.3 199113n

三、unit()函數

unite()函數是將數據框中多列合併為一列,調用公式如下:

> unite(data = ,col = ,... = ,sep = ,remove = )n# col:指定組合為新列的名字n# ...:指定數據中哪些列組合在一起n# sep:組合後新列中數據之間的分隔符n# remove:邏輯值,是否保留參與組合的列n

# 數據準備n> date <- as.Date(2016-11-01) + 0:29n> hour <- sample(1:24,replace = TRUE,30)n> min <- sample(1:60,replace = TRUE,30)n> second <- sample(1:60,replace = TRUE,30)n> event <- sample(letters,30,replace = TRUE)n> data <- data.frame(date,hour,min,second,event)n> head(data,3)n date hour min second eventn1 2016-11-01 23 59 11 yn2 2016-11-02 21 12 4 un3 2016-11-03 2 55 42 in

在這裡,我們使用unite()函數將日期和時間數值合併到一列上。

# date和hour用空格連接n# datehour與時間數值用:連接n> data %>%n+ unite(datehour,date,hour,sep= ) %>%n+ unite(datetime,datehour,min,second,sep=:) %>%n+ head(3)n datetime eventn1 2016-11-01 23:59:1 yn2 2016-11-02 21:12:4 un3 2016-11-03 2:55:42 in

四、separate()函數

在學習了unite()函數後,separate()函數就很好理解了,它的作用正好和unite相反,即將數據框中的某列按照分隔符拆分為多列,一般用於時間序列的拆分,調用公式如下:

> separate(data = ,col = ,into = ,sep = ,remove = ,n+ convert = ,extra = ,fill = ,...)n# col:待拆分的某列n# into:定義拆分後新的列名n# sep:分隔符n# remove:邏輯值,是否刪除拆分後的列n

我們使用上一節得到的時間數據集,定義為data_unite,並對它進行拆分

# 先拆分日期和時間,在對時間進行細拆分n> data_unite %>%n+ separate(datetime,c(date,time),sep= ) %>%n+ separate(time,c(hour,min,second),sep=:) %>%n+ head(3)n date hour min second eventn1 2016-11-01 23 59 1 yn2 2016-11-02 21 12 4 un3 2016-11-03 2 55 42 in

五、缺失值的簡單補齊

> library(readxl)n> data <- read_excel(data.xlsx)n> datan# A tibble: 8 × 2n type numn <chr> <dbl>n1 a 75n2 b 72n3 <NA> 66n4 a NAn5 c 69n6 b 65n7 a 72n8 c NAn

從上面的數據中,我們可以看到類型與數值都存在缺失值。對於類型的缺失值,我們選擇眾數替換,對於數值型的缺失值,我們選擇均值替換(也可選擇中位數等,視具體情況而定)

> num_mean <- mean(data$num, na.rm = TRUE)n> type_mode <- as.character(data$type[which.max(table(data$type))])n> data <- replace_na(data = data, replace = list(num = num_mean, n+ type = type_mode))n> datan# A tibble: 8 × 2n type numn <chr> <dbl>n1 a 75.00000n2 b 72.00000n3 a 66.00000n4 a 69.83333n5 c 69.00000n6 b 65.00000n7 a 72.00000n8 c 69.83333n

附學習文檔:

  1. Introducing tidyr

  2. tidyr包--數據處理包

  3. Data manipulation with tidyr
  4. Data Processing with dplyr & tidyr

  5. Easily tidy data with spread and gather functions

推薦閱讀:

R語言顏色綜合運用與色彩方案共享
[原]數據流編程教程:R語言與非結構化數據共舞
數據分析中常見的七種回歸分析以及R語言實現(二)---逐步回歸
ggplot2繪製漂亮的直方圖
離散顏色標度連續化的最佳實踐

TAG:R编程语言 | 数据分析 | 数据处理 |