นิยามและความสำคัญ

Data manipulation/management คือ การจัดการข้อมูลให้เหมาะแก่การวิเคราะห์ข้อมูล (data analysis) เนื่องจากข้อมูลส่วนใหญ่แล้วอาจจะมีความผิดพลาด เช่น ตัวเลขสูงผิดปกติ น้อยกว่าปกติ จากการพิมพ์ผิด (human error) หรือตัวอย่าง (id) ซ้ำ เป็นต้น นอกเหนือจากความผิดพลาดแล้ว บางครั้งเป็นการจัดการข้อมูลเพื่อให้เหมาะสมหรือสะดวกแก่การวิเคราะห์ตามที่ผู้วิจัยต้องการ

เช่นเดิม คือ ผู้วิจัยควรเริ่มต้นจากการเขียน command พื้นฐาน ดังนี้

rm(list = ls()) # to remove everything
# install.packages("epiDisplay") # install package ในครั้งแรกเท่านั้น (ทำเพียงครั้งเดียว)
library(epiDisplay) # เรียกใช้
## Loading required package: foreign
## Loading required package: survival
## Loading required package: MASS
## Loading required package: nnet
setwd("/Users/polathep/Google Drive/02 PSU/2020/75 Rookie teacher_2020-08-21/Data Analysis_shared folder/01 Introduction to R") # set our working directory - แต่ละคนจะไม่เหมือนกัน
#setwd("D:\\Google Drive\\02 PSU\\2020\\75 Rookie teacher_2020-08-21\\Data Analysis_shared folder\\01 Introduction to R") # set our working directory - แต่ละคนจะไม่เหมือนกัน
dir() # explore our working directory
## [1] "1_Introduction-to-R-program.html" "2_Data-management_part-II.html"  
## [3] "2_Data-management.html"           "birthweight_edited.csv"          
## [5] "birthweight_practice.csv"         "birthweight.csv"                 
## [7] "Icon\r"
bw <- read.csv("birthweight_edited.csv", header = T)
head(bw) # head(…) ใช้สำหรับการอ่านแถวข้อมูลช่วงบน
##   id age lwt  race smoke ptl ht ui ftv  bwt       low
## 1  1  36 202 white    no   0  9  0   1 2836 normal BW
## 2  2  25 120 other    no   0  0  1   2 2877 normal BW
## 3  3  17 120 black    no   0  0  0   2 2438    low BW
## 4  3  17 120 black    no   0  0  0   2 2438    low BW
## 5  4  22 129 white    no   0  0  0   0 4111 normal BW
## 6  5  25 105 other    no   1  0  0   1 2240    low BW


ทำความรู้จักกับ Data “Birthweight”

  1. Description: The birthwt data were collected at Baystate Medical Center, Springfield, Mass during 1986.

  2. This data frame contains the following columns:


ขั้นตอนต่าง ๆ ของ Data manipulation/management

ในที่นี้จะขอสรุปประเด็นที่สำคัญ เรียงเป็นลำดับ ที่ผู้วิจัยควรรู้ ดังนี้

1. บรรยายชุดข้อมูล (describe dataset)

des(bw)
##  
##  No. of observations =  36 
##    Variable      Class           Description
## 1  id            integer                    
## 2  age           integer                    
## 3  lwt           integer                    
## 4  race          character                  
## 5  smoke         character                  
## 6  ptl           integer                    
## 7  ht            integer                    
## 8  ui            integer                    
## 9  ftv           integer                    
## 10 bwt           integer                    
## 11 low           character


2. สรุปชุดข้อมูล (summary)

summary(bw)
##        id             age             lwt            race          
##  Min.   : 1.00   Min.   :14.00   Min.   : 95.0   Length:36         
##  1st Qu.: 7.75   1st Qu.:18.00   1st Qu.:111.5   Class :character  
##  Median :15.50   Median :21.50   Median :120.0   Mode  :character  
##  Mean   :15.19   Mean   :22.39   Mean   :125.3                     
##  3rd Qu.:22.25   3rd Qu.:25.00   3rd Qu.:131.0                     
##  Max.   :30.00   Max.   :36.00   Max.   :202.0                     
##     smoke                ptl               ht              ui       
##  Length:36          Min.   :0.0000   Min.   :0.000   Min.   :0.000  
##  Class :character   1st Qu.:0.0000   1st Qu.:0.000   1st Qu.:0.000  
##  Mode  :character   Median :0.0000   Median :0.000   Median :0.000  
##                     Mean   :0.1389   Mean   :2.306   Mean   :1.833  
##                     3rd Qu.:0.0000   3rd Qu.:3.000   3rd Qu.:1.000  
##                     Max.   :1.0000   Max.   :9.000   Max.   :9.000  
##       ftv              bwt           low           
##  Min.   :0.0000   Min.   :1135   Length:36         
##  1st Qu.:0.0000   1st Qu.:2441   Class :character  
##  Median :1.0000   Median :2898   Mode  :character  
##  Mean   :0.7222   Mean   :3004                     
##  3rd Qu.:1.0000   3rd Qu.:3770                     
##  Max.   :3.0000   Max.   :4111
summ(bw) # epiDisplay pacakge
## 
## No. of observations = 36
## 
##    Var. name obs. mean   median  s.d.   min.   max.  
## 1  id        36   15.19  15.5    8.73   1      30    
## 2  age       36   22.39  21.5    5.33   14     36    
## 3  lwt       36   125.31 120     22.65  95     202   
## 4  race                                              
## 5  smoke                                             
## 6  ptl       36   0.14   0       0.35   0      1     
## 7  ht        36   2.31   0       3.93   0      9     
## 8  ui        36   1.83   0       3.58   0      9     
## 9  ftv       36   0.72   1       0.81   0      3     
## 10 bwt       36   3004.5 2898.5  758.45 1135   4111  
## 11 low


3. ตรวจสอบการซ้ำของข้อมูล (duplication)

ในข้อมูลชุด birthweight_dirty_30.Rds นี้ควรมีจำนวนข้อมูลเพียง 30 แถว แต่ R ระบุว่ามีข้อมูลอยู่ 36 แถว
ซึ่งเกิดจากการมีข้อมูลซ้ำอยู่

duplicated(bw) # This command help us find the duplicated rows
##  [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
## [25]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
bw[duplicated(bw),] # This command show the data from all duplicated rows 
##    id age lwt  race smoke ptl ht ui ftv  bwt       low
## 4   3  17 120 black    no   0  0  0   2 2438    low BW
## 9   7  16 110 other    no   0  9  0   0 3175 normal BW
## 11  8  28 134 other    no   0  9  0   1 3941 normal BW
## 22 18  24 155 white   yes   1  9  0   0 1936    low BW
## 25 20  18 107 white   yes   0  0  1   0 2600 normal BW
## 32 26  21 115 white    no   0  0  9   1 4054 normal BW
bw[duplicated(bw$id),] 
##    id age lwt  race smoke ptl ht ui ftv  bwt       low
## 4   3  17 120 black    no   0  0  0   2 2438    low BW
## 9   7  16 110 other    no   0  9  0   0 3175 normal BW
## 11  8  28 134 other    no   0  9  0   1 3941 normal BW
## 22 18  24 155 white   yes   1  9  0   0 1936    low BW
## 25 20  18 107 white   yes   0  0  1   0 2600 normal BW
## 32 26  21 115 white    no   0  0  9   1 4054 normal BW


เมื่อพบว่ามีชุดข้อมูลซ้ำ ควรจะทำการลบออก โดยมี 2 คำสั่งที่ทำได้

unique(bw) -> bw2
bw[!duplicated(bw),] -> bw2


4. การเปลี่ยนชื่อตัวแปร (rename)

names(bw2)[1] <- "AGE" # variable column ที่ 1 เปลี่ยนชื่อเป็น AGE
names(bw2)[1] <- "age" # เปลี่ยนคืน


5. การเปลี่ยนรหัสค่า (recode)

บ่อยครั้งที่ข้อมูลบางตัวแปรจากผู้ป่วย ไม่มีข้อมูลอยู่ การบันทึกข้อมูลที่เป็น missing value มักใช้ตัวเลข ที่ไม่ซ้ำกับเลขอื่นที่เป็นไปได้ในตัวแปรนั้น เช่น 99 หรือ 999 แล้วมาทำการ recode ในการจัดการข้อมูล ในข้อมูลชุดนี้ ตัวแปร ht ที่เป็น missing value ถูกระบุโดยใช้เลข 9

table(bw2$ht)
## 
##  0  1  9 
## 22  2  6
tab1(bw2$ht) # epiDisplay package

## bw2$ht : 
##         Frequency Percent Cum. percent
## 0              22    73.3         73.3
## 1               2     6.7         80.0
## 9               6    20.0        100.0
##   Total        30   100.0        100.0


การเปลี่ยนค่าทำได้โดยระบุตำแหน่งของค่าที่ต้องการเปลี่ยน และสิ่งที่จะเขียนทับค่าเดิม

bw2$ht[bw2$ht == 9]
## [1] 9 9 9 9 9 9
bw2$ht[bw2$ht == 9] <- NA


เมื่อใช้คำสั่ง table(…) อีกครั้ง จะเห็นได้ว่าไม่มีเลข 9 เหลืออยู่แล้ว

table(bw2$ht)
## 
##  0  1 
## 22  2
tab1(bw2$ht) # epiDisplay package

## bw2$ht : 
##         Frequency   %(NA+)   %(NA-)
## 0              22     73.3     91.7
## 1               2      6.7      8.3
## <NA>            6     20.0      0.0
##   Total        30    100.0    100.0


6. สร้างตัวแปรใหม่ (create new variable)

น้ำหนักเดิมเป็นหน่วยของ pound ซึ่งเราอาจจะไม่คุ้นเคย จึงพิจารณาเปลี่ยนเป็นหน่วย กิโลกรัม (kg) โดยที่ 1 pound = 0.45 kg

summ(bw2$lwt) # epiDisplay package

##  obs. mean    median  s.d.   min.   max.  
##  30   125.667 120     23.7   95     202
bw2$lwt.kg <- bw2$lwt*0.45
summ(bw2$lwt.kg)

##  obs. mean   median  s.d.   min.   max.  
##  30   56.55  54      10.665 42.75  90.9


7. การจัดแบ่งตัวแปร (categorizing data)

หากเราต้องการแบ่งช่วงอายุของมารดาออกเป็น 3 ช่วง คือ < 20 yrs, 20 - 29 yrs, >= 30 yrs

เราสามารถทำได้หลายวิธี โดยบาง package มีคำสั่งที่ช่วยในการ recode โดยเฉพาะ แต่ในวันนี้เราจะทำด้วยคำสั่งพื้นฐาน

  1. สร้างตัวแปรใหม่ โดยดึงค่ามาจากตัวแปรเดิม
  2. เปลี่ยนค่าของตัวแปรใหม่เป็นค่าที่ต้องการ
bw2$agegr <- bw2$age 
bw2$agegr[bw2$age < 20] <- "Gr1: <20"
bw2$agegr[bw2$age >= 20 & bw2$age < 30] <- "Gr2: 20-29"
bw2$agegr[bw2$age >= 30] <- "Gr3: >=30"


ในตอนนี้เราจะได้ตัวแปร agegr ที่เป็นตัวเลข ซึ่งจะต้องระบุให้เป็น factor

bw2$agegr <- factor(bw2$agegr)


ตรวจสอบให้แน่ใจว่าตัวแปรที่สร้างขึ้นใหม่มีค่าที่ถูกต้อง โดยดูจากการกระจายข้อมูลหรือตาราง

table(bw2$agegr,bw2$age)
##             
##              1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
##   Gr1: <20   1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
##   Gr2: 20-29 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  1
##   Gr3: >=30  0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
##             
##              26 27 28 29 30
##   Gr1: <20    0  0  0  0  0
##   Gr2: 20-29  1  1  1  1  0
##   Gr3: >=30   0  0  0  0  1


8. นำข้อมูลออก (save or export data)

หลังจากที่จัดการข้อมูลเรียบร้อยแล้ว เราควรบันทึกข้อมูลเป็นชุดข้อมูลใหม่ สำหรับการวิเคราะห์ทางสถิติต่ิไป
แนะนำให้บันทึกข้อมูลในรูปของ .Rds ซึ่งในการเรียกเข้ามาสู่ R จะใช้เวลาน้อยกว่ารูปแบบอื่น

คำสั่งสำหรับการบันทึกข้อมูล คือ saveRDS

saveRDS(bw2, file = 'bw30_exported.Rds') #  Export to RDS file, named = "bw30_exported.RDS"



และการเรียกกลับเข้าสู่ R ใช้คำสั่ง readRDS

bw30_exported <-  readRDS('bw30_exported.Rds') # Import

สำหรับผู้วิจัยที่อาจจะใช้ program อื่น อาจพิจารณาคำสั่งเหล่านี้

write.csv(bw2, "export_csv.csv") # CSV file
write.dta(bw2, "export_dta_stata.csv") # STATA
write.foreign(bw, "export_data_spss.txt", "export_code_spss.sps", package = "SPSS") # SPSS
write.foreign(bw, "export_data_spss.txt", "export_code_spss.sas", package = "SAS") # SAS