之前在【認識R語言資料結構】中介紹了R語言裡常見的資料結構,並且教導大家如何建立以及閱讀每一種資料結構,而在本篇文章的重點,我們將會介紹更進階處理資料結構的技巧。

一、資料表格長寬轉換

我們在【認識R語言資料結構】文章中有推薦一套件:dplyr,該套件主要功能就是整理資料,讓繁瑣的資料整理變得相當簡單容易,我們在該文章中介紹也實際操作過六大核心函數(filter、select、mutate、summarise、group_by、arrange)。那有時會為了要使分析資料變得容易和讓R讀懂,我們會使用到另外一個Tidtverse家庭中的另一個套件tidyr資料表格長轉寬的技巧。

大家看完敘述可能還不太能理解,讓我們實際操作一次吧:

首先我們用之前我們自己建立的資料框來當作範例使用

consumer <- data.frame(consumer_ID = c(1,2,3,4,5,6,7,8),  

gender=c(‘M’,’F’,’F’,’M’,’F’,’F’,’F’,’M’),

age = c(18,20,21,24,40,33,49,19),

purchase_item=c(“A1″,”A2″,”A1″,”B1″,”B3″,”A1″,”C2″,”C1”),

payment_method=c(“C”,”C”,”M”,”C”,”M”,”D”,”C”,”M”)), 

cost = c(100,200,100,300,600,100,450,350)

我們所建立出來的這個資料框(表格),是所謂的寬表格(wide format),寬表格的特性就是每一列(row)會包含多個觀察值,如編號2的顧客那一列就會顯示為女性、年齡是20、購買品項是A2、付款方式是現金以及花費200元。可以看到寬表格的優點即為呈現的資料量多!接著我們就直接先這個寬表格轉換成長表格,再來看長表格的特性。

要轉換表格,先載入tidyr套件,並使用寬轉長gather() 函數,

#載入套件

install.packages(“tidyr”)

library(tidyr)

#使用gather()函數

con_long <- gather(data = consumer, key = “主鍵”, value = “對應值”, age,cost)

在長表格(long format)中,會有所謂的主鍵(Key)也可以當成是類別變數,以及其對應的數值(Value),那麼就必須在gather()函數中去輸入我們想要聚集( 範例以age,cost) 的數值欄位以及命名。在執行之後,會出現以下表格形式:

可以看到長表格呈現的方式,會以使用者主要想觀察的Key值來做排序呈現,我們不難發現長表格的特性就是每一列(row)只會有一個觀察值(age或cost)。

那學會由寬表格轉成長表格,我們再學由長表格轉為寬表格,而要使用到的函數是  spread() 函數  :

#長轉寬表格 使用spread()函數

con_width <- spread(con_long, key = “主鍵”, value = “對應值”)

View(con_width)

方法是要指定長表格的名稱、主鍵的欄位還有對應值的欄位,執行之後我們檢視它,會發現它就會轉換成我們原來所建立的寬表格資料框!

*總結以上,若是要在寬表格新增額外的資訊,就要新增一個新欄位(例如新增職業類別)。而若是要在長表格中新增資訊,則要新增一個列數(例如新增體身高、體重等)。

二、資料分割與合併

資料分割與合併是進行資料分析之前相當重要的一個環節,尤其像是在做建立迴歸模型、分類模型等會用到的測試資料和訓練資料,就必須利用到分割原始資料和重新分配以及合併資料的的步驟,有了這些步驟才能夠順利的製作出所需要的訓練資料和測試資料。

(一)資料分割

主要使用subset()函式,可以依據你想要的特定變數數值,來進行選擇且切割出來,用我們創建的資料框來做示範(希望將年齡>30歲和年齡<30的消費者資料個別切割出來)

#在subset()函式的第一格內要放的是原始資料集合(欲分割的資料集合)

consumer_old <- subset(consumer, age>30 )

View(consumer_old) #即將原始資料框年齡>30的消費者資料切割出來

 

consumer_young <- subset(consumer, age<30 )

View(consumer_young) #即將原始資料框年齡<30的消費者資料切割出來

而若我們只想要將年齡>30歲消費者的消費金額分割出來,即在subset函式裡加上一個selcet=即可:

consumer_old <- subset(consumer, age>30, select = cost)

#select= cost 代表只想將cost(消費金額)資料分割出來

View(consumer_old)

consumer_old <- subset(consumer, age>30, select = -cost)

#select= -cost 同理,代表只想將除了cost(消費金額)資料分割出來

View(consumer_old)

(二)資料合併

當我們在進行兩筆以上的資料合併時,主要會使用rbind()函式和cbind()函式,都可以將兩筆資料進行合併,但兩種函式在功能以及限制上都有些微差異,以下進行示範:

1.其中使用rbind()函式時,需要注意對應欄位變數名稱,否則將無法進行合併:

new_consumer <- rbind(consumer_old,consumer_young)

#使用rbind()函式,將欲合併的兩筆資料框依序放入函式中

View(new_consumer)

2.使用cbind()函式時,可以用來新增變數到原始資料框中,不需要對應欄位變數名稱:

#首先我們再次創建兩種資料框(一是消費者年齡和性別、二是其餘資料)

c1 <-

data.frame(gender=c(‘M’,’F’,’F’,’M’,’F’,’F’,’F’,’M’),

age = c(18,20,21,24,40,33,49,19))

 

c2 <-

data.frame(consumer_ID = c(1,2,3,4,5,6,7,8), 

purchase_item=c(‘A1′,’A2′,’A1′,’B1′,’B3′,’A1′,’C2′,’C1’),

payment_method=c(“C”,”C”,”M”,”C”,”M”,”D”,”C”,”M”),    

cost=c(100,200,100,300,600,100,450,350))

 

#接著使用cbind()函式將兩資料框進行合併

new_consumer <- cbind(c1,c2)

#將欲合併的資料框依序放入cbind()函式中

View(new_consumer)

這樣是否了解使用rbind()函式和cbind()函式在使用上的差異了呢,因此再遇到不同情況時,記得要選擇對的合併方式,才不會出現error喔!

另外還有一個函數merge()也能夠用做合併資料,個人認為是一個功能較為整合的一個函式。

3.使用函數merge(),可以依據兩資料框裡某個相同變數,將兩筆資料進行合併處理:

#首先我們再次創建兩種資料框(一是消費者年齡和性別、二是其餘資料,但兩資料框都具備有消費者ID)

c1 <-

data.frame(consumer_ID = c(1,2,3,4,5,6,7,8,9),                      

gender=c(‘M’,’F’,’F’,’M’,’F’,’F’,’F’,’M’,’M’),

age = c(18,20,21,24,40,33,49,19,20))

 

c2 <-

data.frame(consumer_ID = c(1,2,3,4,5,6,7,8,10),                       purchase_item=c(‘A1′,’A2′,’A1′,’B1′,’B3′,’A1′,’C2′,’C1′,’C3’),

payment_method=c(“C”,”C”,”M”,”C”,”M”,”D”,”C”,”M”,”C”),                       cost=c(100,200,100,300,600,100,450,350),400)

#特別注意,這裡故意將consumer_ID欄位設置成有差異(9,10)

 

#接著利用merge()函式,將具備consumer_ID欄位的兩資料框進行合併

new_consumer <- merge(c1,c2,by=”consumer_ID”)

View(new_consumer)

#完成合併並顯示出consumer_ID欄位且有相同ID的消費者(1~8)所有資料

#因故意將consumer_ID設置兩碼不一樣(9,10),可以透過all = T(詢問是否觀察所有資料),來看編號9和10什麼資料是空缺的。

new_consumer <- merge(c1,c2,by=”consumer_ID”,all = T)

View(new_consumer)

*總結以上,資料分割與合併是資料預處理階段相當重要的環節,同學們應了解每個函數的使用方法以及使用限制,未來拿到多筆資料時,才能得心應手。

三、資料類型檢查以及資料結構轉換

當我們匯入一新資料集合時,首先要先確認每個變數的類別型態,若直接進行統計分析,系統容易會產生error,因此我們在確認資料類型就相當重要了。那要判斷類型很簡單,以下有兩種方式介紹給大家:

確認是否是文字型態 is.character()

確認是否是數值型態 is.numeric()

確認是否是布林代數型態 is.logical()

#確認變數型態

is.character(consumer$age)

is.numeric(consumer$age)

is.logical(consumer$age)

我們就利用之前建立的顧客資料框的年齡變數來確認,因為年齡是以數值紀錄的,因次可以看到除了is.numeric是TRUE,其他都是FALSE喔!

那以上這種方式會比較慢,因為在你不知道變數類型的時候,你必須一個一個去試試看,但若用另一種方式class() 就會立刻回傳資料型態給我們,非常方便:

class(consumer$cost)

class(consumer$age)

class(consumer$purchase_item)

這樣是不是比較快速呢?那就看大家比較喜歡哪一種方式囉~

接著在確認完變數類型之後,當這個變數類型不是我們想要時,我們不需要重新新增與輸入一欄,我們可以直接改變該欄的變數類型,使用:

as.numeric() 轉成數字型態

as.character() 轉成文字型態

as.logical()  轉成布林代數型態

#將年齡變數改為文字型態

newage <- as.character(consumer$age)

class(newage)

#將性別變數改為數值型態

newgenger <- as.numeric(consumer$gender)

class(newgenger)

newgenger

四、虛擬變數(Dummy variable)轉換

在迴歸分析(一般線性迴歸、羅吉斯迴歸)當中,當自變數為類別變數時,我們都要先進行轉換虛擬變數(Dummy variable)的動作,以人工方式將變數量化為類別變數,通常取值會以0或1存在。

轉換時我們會使用到dummies套件中的dummy.data.frame()函式,以下一樣使用我們創建的消費者資料框進行示範:

#複習一下,使用套件時,需先行安裝套件並且啟動該套件才能使用套件裡函數的功能喔!

install.packages(‘dummies’)

library(‘dummies’)

consumer_dummy <- dummy.data.frame(consumer)

View(consumer_dummy)

#該函式會自動抓取資料框中factor資料類型的變數進行轉換

consumer_dummy <- dummy.data.frame(consumer,all = F)

#可以利用 all=F 來觀察有轉換過後的資料

 而若今天我們只想要分析該資料框中某一個變數時,我們也可以利用model.matrix()函式轉換的該欄位的資料,但要特別注意的是該欄位之變數必須以factor型態存在,否則將無法轉換,因此需要提前轉換好資料型態:

#將資料框中的性別變數轉為虛擬變數

consumer_gender_dummy <- model.matrix(~consumer$gender-1)

View(consumer_gender_dummy)

 

#將資料框中的付款方式變數轉為虛擬變數

consumer_method_dummy <-model.matrix(~consumer$payment_method-1)

View(consumer_method_dummy)

 

#將資料框中的購買品項變數轉為虛擬變數

consumer_item_dummy <- model.matrix(~consumer$purchase_item-1)

View(consumer_item_dummy)

*小結:以上內容就是進階的資料處理,結合【認識R語言資料結構】文章中的dplyr資料處理,就是大家在處理資料時最需要用到的技巧,而這些內容是我們在做資料分析前必要的過程,因此又稱為資料預處理。