พื้นฐานการเขียนโปรแกรมด้วยภาษา R

ผู้เขียน: ธีรศักดิ์ เอโกบล

ข้อมูลทางชีววิทยามีหลายรูปแบบ สามาถแบ่งได้เป็น 2 ประเภทหลัก คือ

  1. ข้อมูลเชิงคุณภาพ (Qualitative data) 1.1 Nominal data เป็นข้อมูลที่ไม่มีลำดับ เช่น เพศ เชื้อชาติ 1.2 Ordinal data เป็นข้อมูลที่มีอันดับ (order) เช่น ระดับความรุนแรง ประสิทธิภาพการทำงาน 1.3 Binary data เป็นข้อมูลที่มีเพียงสองตัวเลือก เช่น ผ่านหรือไม่ผ่าน ใช่หรือไม่ใช่ ปีกยาวหรือปีกกุด
  2. ข้อมูลเชิงปริมาณ (Quantitative data) 2.1 Discrete data เป็นข้อมูลที่ไม่ต่อเนื่อง สามารถจัดกลุ่ม (cassification) โดยการนับความถี่ (counting) เช่น จำนวนของเซลล์ จำนวนของนกที่นับได้จากการสำรวจ 2.2 Continuous data เป็นข้อมูลที่มีค่าต่อเนื่อง เช่น ความสูง น้ำหนัก

ภาษา R พัฒนาโดย John Chambers เป็นภาษาที่นิยมใช้และมีประสิทธิภาพในการวิเคราะห์ข้อมูลทางชีววิทยารูปแบบต่างๆ สามารถติดตั้งภาษา R ได้จาก https://www.r-project.org/ ภาษา R มีการพัฒนาและปรับปรุงอย่างต่อเนื่อง มีการพัฒนาแพคเกจ (package) และไลบรารี (library) ใหม่ๆ อยู่ตลอด สามารถนำมาใช้งานโดยไม่เสียค่าใช้จ่าย การเขียนโปรแกรมด้วยภาษา R มีโปรแกรมช่วยเขียนภาษาให้เลือกใช้ได้หลายโปรแกรม เช่น RStudio หรือ [jupyter notebook] (https://jupyter.org/) ซึ่งสามาถติดตั้งได้อย่างสะดวกผ่านโปรแกรม anaconda ในการเริ่มต้นเขียนโปรแกรมภาษา R จะเปิดโปรแกรม anaconda navigator กำหนดค่า environment สำหรับภาษา R และ Python โดยเลือกเวอร์ชั่นที่เหมาะสม แล้วจึงเปิดใช้งาน jupyter notebook เพื่อเริ่มต้นการเขียนคำสั่งหรือโค้ด (coding หรือ programming หรืออาจเรียกว่า scripting)

การเขียนภาษา R ด้วยโปรแกรม RStudio สามารถดาวน์โหลดโปรแกรมนี้ได้จาก https://rstudio.com/ โดยต้องทำการติดตั้งาษา R ก่อนเช่นกัน โปรแกรม RStudio เป็นโปรแกรมช่วยเขียนภาษาที่สามารถแนะนำและตรวจแก้เบื้องต้นหากพิมพ์ผิดหลักของภาษาได้ (syntax error) โดยสามารถศึกษาวิธีใช้งานโปรแกรม RStudio เบื้องต้นได้ที่ https://youtu.be/sBCnbAdQNBM โดยไฟล์ภาษา R จะบันทึกด้วยสกุล .R ซึ่งสามารถแบ่งปันหรือเปิดกลับมาแก้ไขในภายหลังได้

ผู้เริ่มต้นเขียนโปรแกรมสามารถใช้โปรแกรม jupyter notebook ในการเขียนคำสั่งในเซลล์ (cell) สำหรับเขียนคำสั่ง (code cell) แล้วรันคำสั่ง (run หรือ execute) เพื่อดูผลลัพธ์ (output) ที่แสดงให้เห็นได้เลย และสามารถเขียนข้อความเพื่ออธิบายประกอบคำสั่งหรือโปรแกรมในเซลล์สำหรับเขียนข้อความ (markdown cell) ได้ สามารถทดลองเขียนคำสั่งแสดงผลข้อความอย่างง่ายด้วยฟังก์ชั่น (function) print()

In [1]:
# first R command
print("Hello R.")
[1] "Hello R."

การเริ่มต้นเขียนโปรแกรมนั้นคล้ายคล้ายกับการเรียนรู้ภาษา คือเรียนรู้ตัวอักษร (character) เพื่อประกอบเป็นคำ (word) ประเภทต่างๆ แล้วสร้างเป็นประโยค (sentence) เพื่อใช้ในการสื่อสารกับหน่วยประมวลผลของคอมพิวเตอร์ให้ดำเนินการตามขั้นตอนที่ผู้เขียนโปรแกรม (programmer) ต้องการ

คำที่ใช้ในการเขียนโปรแกรมแบ่งเป็นประเภทต่างๆ ได้แก่

  1. ค่าคงที่ (constant) เป็นคำที่เก็บค่าเพียงค่าเดียวและไม่สามารถเปลี่ยนแปลงได้ เช่น 1.1 จำนวน (number) ได้แก่
         a. จำนวนเต็ม (integer) ได้แก่ 1, 2, 3,...
         b. เศษส่วนหรือทศนิยม (float หรือ double) ได้แก่ 2.3, 0.001, ...
    
    1.2 ตัวอักษร (character) เช่น 'A' 'B' 'T' และข้อความ (string) คือลำดับของตัวอักษร เช่น 'ATGCGGACCCCA' หรือ "Cat has four legs." ค่าคงที่ประเภทนี้จะต้องเขียนอยู่ภายในเครื่องหมาย ' หรือ " 1.3 คำเฉพาะ (reserved words) สำหรับดำเนินการเฉพาะในภาษา R ได้แก่ in for while if else repeat break TRUE FALSE และ NA
  2. ตัวแปร (variable) เป็นคำที่สามารถเปลี่ยนค่า (value) ที่เก็บไว้ภายในได้ การกำหนดชื่อตัวแปรในภาษา R ต้องไม่มีการเว้นวรรค ไม่ขึ้นต้นด้วตัวเลขหรือสัญลักษณ์ ชื่อตัวแปรที่ประกอบด้วยตัวอักษรพิมพ์ใหญ่ (uppercase) หรือเล็ก (lowercase) จะไม่เหมือนกันเช่น DNA dna หรือ Dna จะไม่ใช่ตัวแปรเดียวกัน ภายในชื่ของตัวแปรสามารถคั่นด้วย .(dot) _ (underscore) หรือมีตัวเลขได้ เช่น DNA_plant หรือ rna.sample1
  3. ตัวดำเนินการ (operator) ใช้สำหรับดำเนินการคำนวนของตัวแปรหรือค่าคงที่ แบ่งเป็น 3.1 ตัวดำเนินการทางคณิตศาสตร์ (mathematical operator) ได้แก่ บวก (+) ลบ (-) คูณ (*) หาร (/) ยกกำลัง (^) ค่าสัมบูรณ์ (abs()) ลอการิทึม (log()) รากที่สอง (sqrt()) หารตัดเศษ (%/%) หารเอาส่วน (%%) 3.2 ตัวดำเนินการทางตรรกศาสตร์ (logical operators) สำหรับการเปรียบเทียบเชิงตรรกะ ได้แก่ และ (&) หรือ (|) นิเสธ (!) 3.3 ตัวดำเนินการเพื่อกำหนดค่าใช้เครื่องหมาย = หรือ <- 3.4 ตัวดำเนินงานสำหรับกำหนดเงื่อนไข (boolean operators) ในการเปรียบเทียบ ได้แก่ เท่ากับ (==) ไม่เท่ากับ (!=) มากกว่า (>) น้อยกว่า (<) มากกว่าหรือเท่ากับ (>=) น้อยกว่าหรือเท่ากับ (<=) 3.5 ตัวดำเนินการพิเศษ (special operators) เช่น ; ใช้สำหรับคั่นคำสั่ง : ใช้สำหรับการกำหนดช่วงของข้อมูล (index)
  4. ฟังก์ชั่น (function) เป็นชุดของคำสั่งสำหรับดำเนินการอย่างใดอย่างหนึ่งที่มีการพัฒนาไว้แล้วก่อนหน้า ผู้ใช้สามารถนำชุดคำสั่งนี้มาใช้โดยไม่จำเป็นต้องรู้ว่าฟังก์ชั่นนั้นๆ เขียนขึ้นมาอย่างไร เป็นการนำชุดคำสั่งกลับมาใช้ที่ช่วยลดระยะเวลา (reuse) ในการเขียนโปรแกรมได้ ลักษณะของฟังก์ชั่นจะประกอบด้วยชื่อและตามด้วยวงเล็บ ( ) เช่น
    • print() เป็นชุดคำสั่งสำหรับแสดงผลบนหน้าจอ
    • paste() คำสั่งในการแสดงผลเป็นข้อความบนหน้าจอ
    • mean() ชุดคำสั่งเพื่อคำนวณค่าเฉลี่ย
    • plot() ชุดคำสั่งเพื่อแสดงผลกราฟิก (graphic)
    • ls() เป็นชุดคำสั่งเพื่อแสดงรายการของอ็อคเจ็ค
    • help() เป็นชุดคำสั่งเพื่อแสดงเมนูช่วยเหลือหรือเอกสารที่เกี่ยวข้องกับคำค้น
    • getwd() เป็นชุดคำสั่งเพื่อเรียกดูตำแหน่งปัจจุบันที่ทำงานอยู่ (working directory)
    • data() เป็นชุดคำสั่งเพื่อเรียงดูชุดข้อมูลที่มีอยู่ (data sets)
      หากมีฟังก์ชั่นจำนวนมากสำหรับดำเนินการในงานประเภทเดียวกัน อาจรวมกันเป็นแพคเกจ (package) และไลบรารี (library) ได้ ซึ่งแพคเกจหรือไลบรารี่ในภาษา R นั้นอาจเป็นแพคเกจและไลบรารี่ที่มีอยู่แล้วในโปรแกรม (built-in) หรือเป็นแพคเกจและไลบรารี่ที่ผู้อื่นพัฒนาขึ้นมาแล้วเผยแพร่ให้ผู้อื่นนำไปใช้งานได้ สำหรับการติดตั้งแพคเกจและไลบรารี่ใหม่ด้วยโปรแกรม RStudio นั้นทำได้โดยเลือกเมนู Tools > Install Packages พิมพ์ชื่อของแพคเกจหรือไลบรารี่ที่สนใจ เมื่อกดปุ่มดาวน์โหลด โปรแกรมจะดำเนินการดาวน์โหลดและติดตั้งให้แพคเกจหรือไลบรารี่พร้อมใช้งาน หรือทำการติดตั้งด้วยฟังก์ชั่น install.packages("ชื่อของแพคเกจ") ส่วนการเรียกใช้งานแพคเกจหรือไลบรารี่ทำโดยใช้ฟังก์ชั่น library() ปัจจุบันมีแพคเกจและไลบรารี่ที่พัฒนาด้วยภาษา R และเปิดให้ใช้ได้ฟรีเป็นจำนวนมาก สามารถศึกษารายละเอียดได้จาก https://cran.r-project.org/web/packages/ (16,285 แพคเกจ ณ 16 กันยายน 2563) โดยแพคเกจเหล่านี้พัฒนาขึ้นเพื่อการวิเคราะห์ จัดการและนำเสนอข้อมูลจากงานวิจัยด้านต่างๆ แพคเกจและไลบรารี่ที่นิยมใช้สำหรับการวิเคราะห์และนำเสนอข้อมูลในปัจจุบันได้แก่
    • dplyr เป็นแพคเกจสำหรับการจัดการข้อมูล (data manipulation)
    • ggplot2 เป็นแพคเกจสำหรับการนำเสนอข้อมูล (data presentation)
    • shiny เป็นแพคเกจสำหรับการสร้างแอพพลิเคชั่น (application)
    • car เป็นแพคเกจสำหรับการวิเคราะห์ ANOVA
In [8]:
3.14 #double
typeof(3.14) #show type

"ATG" #character
typeof("ATG")

TRUE #logical words
typeof(TRUE)

#Basic math calculation
11/2 #division
11%/%2 #integer divide
11%%2 #modulus
11^2 #exponential
pi #Pi constant
3 == 4 #logical comparisons
100 > 50
(3 == 4) & (100 > 50)

r = 7 #assign radial value of 7 to a variable named r 
circle_area = pi*r*r #calcular the area of the circle and keep the result in circle_area
circle_area #show the result
print(circle_area) #display the value kept inside the circle_area variable

# use paste function to show the result on the screen
# the showed result can be mixed between String/text and values in the variables.
paste("The area of the circle with radius of ", r, " = ", circle_area)

data() #show available data sets
getwd() #get working directory

seq(from = 2, to = 5) #function to generate a sequence of numbers
3.14
'double'
'ATG'
'character'
TRUE
'logical'
5.5
5
1
121
3.14159265358979
FALSE
TRUE
FALSE
153.9380400259
[1] 153.938
'The area of the circle with radius of 7 = 153.9380400259'
'C:/Users/TeerasakArt/Downloads'
  1. 2
  2. 3
  3. 4
  4. 5

การนำคำต่างๆ ในภาษา R มาประกอบเป็นประโยคสามารถทำได้หลายรูปแบบ เช่น

  1. การกำหนดค่า (assignment) เป็นการกำหนดค่าให้กับตัวแปรเพื่อเก็บข้อมูลหรือนำไปดำเนินการ เช่น x = 10 หรือ protein = "AGDFSVBBLIPPPPBNHD"
  2. การดำเนินการ (operation หรือ expression) เป็นการนำตัวแปรหรือค่าคงที่มาคำนวณหรือดำเนินการโดยอาจมีการเก็บผลลัพธ์ที่ได้ในตัวแปรเพื่อนำไปใช้งานต่อ เช่น x = y + 10 หรือ mergedDNA = paste("AAAAA", "TTTTTT", sep="") โดยการดำเนินการทางด้านขวาของเครื่องหมาย = จะเก็บผลไว้ในตัวแปรทางด้านซ้าย
  3. การเปรียบเทียบ (comparison) เป็นการเปรียบเทียบค่าคงที่หรือตัวแปรว่าเป็นไปตามเงื่อนไขที่กำหนดหรือไม่ เช่น x == y หรือ (y > 10) & (y < 100)
In [9]:
#assignment
x = 10
x #display value stored in the variable

protein = "AGDFSVBBLIPPPPBNHD"
protein

nucleotide = c('A', 'T', 'C', 'G') #a variable can keep multiple values.
print(nucleotide)

#operation
y = 4
x = y + 10
x

mergedDNA = paste("AAAAA", "TTTTTT", sep="")
mergedDNA
print(mergedDNA)
paste(mergedDNA)

#comparison
x == y
(y > 10) & (y < 100)
10
'AGDFSVBBLIPPPPBNHD'
14
'AAAAATTTTTT'
[1] "AAAAATTTTTT"
'AAAAATTTTTT'
FALSE
FALSE

ในตัวอย่างข้างต้น เครื่องหมาย # ใช้สำหรับเขียนข้อความที่ไม่ใช่คำสั่งภายในโปรแกรม (comments) โดยโปรแกรม R จะไม่ดำเนินการใดๆ กับข้อความเหล่านี้ สามารถใช้การเขียนคอมเมนต์เพื่ออธิบายรายละเอียดและการทำงานโปรแกรม

การนำประโยคเหล่านี้มาประกอบเป็นข้อความ (paragraph) หรือโปรแกรมที่ยาวขึ้นเพื่อดำเนินการแก้ปัญหาที่สนใจ หรือเมื่อต้องพิมพ์คำสั่งเดิมในการดำเนินการแบบเดิมซ้ำกันหลายหน ทำให้ดำเนินการได้รวดเร็วมากขึ้น สามารถใช้รูปแบบดังต่อไปนี้มาช่วยได้

  1. การทำซ้ำ (repetition หรือ iteration) โดยใช้โครงสร้างของ for หรือ while 1.1 while loop ใช้ในการทำซ้ำตามเงื่อนไขที่กำหนดจนกระทั่งเงื่อนไขนั้นไม่เป็นจริง (FALSE) โครงสร้างของ while loop จะต้องกำหนดตัวแปรเพื่อเก็บค่าเริ่มต้นแล้วทำการเพิ่ม (increment) หรือลดค่า (decrement) ของตัวแปรนี้ แล้วตรวจสอบเงื่อนไขจนกระทั่งเป็นเท็จ โดยมีรูปแบบการเขียนดังตัวอย่าง
In [4]:
#while loop
num = 1 #starting value
while(num <10){  #condition
    x = paste("Gene", num, sep = "_") #command 1
    print(x)                          #command 2 
    num = num + 1                     #command 3
} #end of the loop
[1] "Gene_1"
[1] "Gene_2"
[1] "Gene_3"
[1] "Gene_4"
[1] "Gene_5"
[1] "Gene_6"
[1] "Gene_7"
[1] "Gene_8"
[1] "Gene_9"

ตัวอย่างข้างต้นเป็นการใช้ while loop เพื่อกำหนดชื่อของยีนตามลำดับตัวเลข

1.2 **for loop** ใช้ในการทำซ้ำตามจำนวนหรือช่วงของจำนวนที่กำหนดในเงื่อนไขแล้วหยุดเมื่อครบตามจำนวน โดยมีรูปแบบการเขียนดังตัวอย่าง
In [5]:
#for loop
for(i in 1:10){ #condition
    x = paste("Gene", i, sep = "_") #command 1
    print(x)                          #command 2
}
[1] "Gene_1"
[1] "Gene_2"
[1] "Gene_3"
[1] "Gene_4"
[1] "Gene_5"
[1] "Gene_6"
[1] "Gene_7"
[1] "Gene_8"
[1] "Gene_9"
[1] "Gene_10"

จากตัวอย่าง สามารถใช้ for loop เพื่อทำซ้ำในการกำหนดชื่อยีนตามลำดับตัวเลขเหมือนที่เขียนด้วย while loop ได้ แต่ไม่ต้องกำหนดการเพิ่มหรือลดค่าของตัวแปร เงือนไข i in 1:10 ระบุว่าให้ R ตรวจสอบค่าของ i ว่ามีค่าอยู่ตั้งแต่ 1 ถึง 10 หรือไม่ โดย in เป็นคำเฉพาะเพื่อใช้ตรวจสอบการเป็นสมาชิกของค่าที่กำหนด และ 1:10 เป็นการกำหนดข้อมูลจำนวนนับ 1, 2, 3, ..., 10

  1. การกำหนดเงื่อนไข (conditional statement) เป็นการสร้างเงื่อนไขเพื่อกำหนดการดำเนินการของโปรแกรมโดยใช้ if if...else if...else if...else หรือ nested if หากเงื่อนไขหนึ่งผ่านจะดำเนินการคำสั่งภายใต้เงื่อนไขนั้น รูปแบบการเขียนแสดงในตัวอย่างดังนี้
In [6]:
#if...else
x = 150
if(x > 100){ #condition 1
    #command if condition 1 is true
    y = paste("your blood sugar is", x, "mg/dL. You have high blood sugar.")
    print(y)
}else{ #condition 2
    #command if condition 2 is true
    y = paste("your blood sugar is", x, "mg/dL. You have normal blood sugar.")
    print(y)
}
[1] "your blood sugar is 150 mg/dL. You have high blood sugar."

จากตัวอย่างของ if...else จะมีสองเงื่อนไข เงื่อนไขแรกของ if หากระดับน้ำตาลในเลือดมากกว่า 100 mg/dL จะพิมพ์ข้อความว่ามีระดับน้ำตาลในเลือดสูง หากไม่เป็นไปตามเงื่อนไขนี้ โปรแกรมจะดำเนินการคำสั่งในเงื่อนไขของ else หากมีหลายเงื่อนไขควรใช้ if...else if...else ดังตัวอย่างนี้

In [7]:
#if...else if....else
score = 70
if(score >= 80){
    grade = 'A'
}else if(score >= 75 & score <80){
    grade = 'B+'
}else if(score >= 70 & score <75){
    grade = 'B'
}else if(score >= 65 & score <70){
    grade = 'C+'
}else if(score >= 60 & score <65){
    grade = 'C'
}else if(score >= 55 & score <60){
    grade = 'D+'
}else if(score >= 50 & score <55){
    grade = 'D'
}else{grade = 'F'}
print(paste("You got", grade, '.'))
[1] "You got B ."

ข้างต้นเป็นตัวอย่างการใช้ if...else if...else เพื่อระบุเกรดจากเกณฑ์คะแนนที่กำหนด ในตัวอย่างนี้มีมากกว่าสองเงื่อนไข โดยโปรแกรมจะตรวจค่าของ score กับทุกเงื่อนไข หากค่าของ score ผ่านเงื่อนไขใด โปรแกรมจะดำเนินการตามคำสั่งในเงื่อนไขนั้น คือกำหนดค่าของตัวแปร grade เพื่อแสดงผลโดยรวมข้อความด้วยฟังก์ชั่น paste() และแสดงผลที่หน้าจอด้วยฟังก์ชั่น print() หากมีเงื่อนไขย่อยภายในเงื่อนไขหลัก ควรใช้โครงสร้างแบบ nested if ดังตัวอย่าง

In [8]:
mom = "Aa"
dad = "Aa"
if(mom == "AA"){
    if(dad == "AA"){child = "AA"
                   }else if(dad == "Aa"){child = "1AA : 1Aa"
                                        }else{child = "Aa"}
}else if(mom == "Aa"){
    if(dad == "AA"){child = "1AA : 1Aa"
                   }else if(dad == "Aa"){child = "1AA : 2Aa : 1aa"
                                        }else{child = "1Aa : 1aa"}
}else{
    if(dad == "AA"){child = "Aa"
                   }else if(dad == "Aa"){child = "1Aa : 1aa"
                                        }else{child = "aa"}
}
print(paste("If mom and dad are", mom, "and", dad, ".", " The children will be", child, "."))
[1] "If mom and dad are Aa and Aa .  The children will be 1AA : 2Aa : 1aa ."

ตัวอย่างนี้แสดงการใช้ nested if เพื่อจับคู่จีโนไทป์ที่เป็นไปได้แต่ละแบบของแม่กับจีโนไทป์ที่เป็นไปได้ของพ่อ แล้วแสดงผลเป็นสัดส่วนจีโนไทป์ที่เป็นได้ในรุ่นลูก

ประเภทของข้อมูล (Data types หรือ data objects)

การเขียนโปรแกรมด้วยภาษา R เพื่อจัดการกับข้อมูลประเภทต่างๆ มีอ็อบเจ็ค (object) หรือโปรแกรมเชิงวัตถุสำหรับช่วยดำเนินการข้อมูลโดยอ็อบเจ็คจะมีลักษณะเฉพาะ (attritubue หรือ characteristics) และความสามารถของอ็อคเจ็คนั้นในการดำเนินการด้วยคำสั่งหรือฟังก์ชั่นที่เหมาะสม (method function หรือ ability) เช่น การสร้างอ็อบเจ็ค (creating) การตั้งชื่อ (naming) การเลือกข้อมูลที่ต้องการหรือทำดัชนี (indexing) การแทนที่ (replacing) และการดำเนินการ (operating) อ็อบเจ็คที่นิยมใช้กับข้อมูลประเภทต่างๆ ได้แก่

1. เวคเตอร์ (vector) ใช้สำหรับเก็บข้อมูลที่มีลำดับ (order) เป็นจำนวนหรือตัวอักษร โดยใช้ฟังก์ชั่น comcatenate หรือ c() เช่น

In [12]:
nucleotide = c('A', 'T', 'G', 'C') #create a vector named nucleotide
nucleotide

nucleotide[2] #show the second value in the vector
nucleotide[2:3] #show the second and third values
nucleotide[c(1,4)] #show the first and forth values

nucleotide[1] = 'a' #replace a value at the first position
nucleotide
  1. 'A'
  2. 'T'
  3. 'G'
  4. 'C'
'T'
  1. 'T'
  2. 'G'
  1. 'A'
  2. 'C'
  1. 'a'
  2. 'T'
  3. 'G'
  4. 'C'

2. แมทริกซ์ (matrix) เป็นอ็อบเจ็คที่เก็บข้อมูลประเภทเดียวกัน (ตัวเลข ตัวอักษร หรือตัวตรรกะ) ประกอบด้วยแถว (row) และคอลัม (column) สร้างแมทริกซ์ด้วยฟังก์ชั่น matrix() โดยระบุพารามิเตอร์ (parameter) หรืออารฺกิวเมนต์ (argument) เพื่อกำหนดจำนวนแถว (nrow) จำนวนคอลัม (ncol) จัดข้อมูลตามแนวแถว (byrow) และกำหนดชื่อคอลัมและแถว (dimnames) เช่น

In [24]:
nucleotide = c('A', 'T', 'G', 'C')

#create a matrix named dnaMatrix
dnaMatrix = matrix(nucleotide, nrow = 2, ncol = 2, byrow = FALSE, dimnames = list(c('purine', 'pyrimidine')))
dnaMatrix

dnaMatrix[1, 2] #select data at the first row and second column
dnaMatrix[, 2] #select only the second column

#create a vector that contains DNA nucleotide substitution values
substitutionValue = c(0.81, 0.10, 0.0, 0.02,
                     0.07, 0.87, 0.03, 0.03,
                     0.16, 0.12, 0.71, 0.01,
                     0.07, 0.26, 0.05, 0.62)

#create a substitution matrix
substitutionMatrix = matrix(substitutionValue, nrow = 4, ncol = 4, 
                           byrow = TRUE, dimnames = list(c('A', 'T', 'G', 'C'), c('A', 'T', 'G', 'C')))
substitutionMatrix

substitutionMatrix[1:2, 3:4]  #subset the matrix
purineAG
pyrimidineTC
purine: 'G'
purine
'G'
pyrimidine
'C'
ATGC
A0.810.100.000.02
T0.070.870.030.03
G0.160.120.710.01
C0.070.260.050.62
GC
A0.000.02
T0.030.03

ตัวอย่างข้างต้นอ็อบเจ็ค substitutionMatrix เป็นแมทริกซ์ขนาด 4 แถว 4 คอลัม เก็บข้อมูลความน่าจะเป็นในการเปลี่ยนแปลงนิวคลีโอไทด์ของการกลายแบบการแทนที่นิวคลีโอไทด์ จะเห็นว่าแมทริกซ์นี้เก็บข้อมูลชนิดจำนวนเท่านั้น

3. แอเรย์ (array) คือแมทริกซ์ที่มีมากกว่าสองมิติ ใช้ฟังก์ชั่น array() ในการสร้าง เช่น การสร้างแอเรย์เพื่อเก็บข้อมูลตารางรหัสพันธุกรรม เป็นตารางขนาด 8 x 8 x 2

In [4]:
#create a vector of codons
codon = c('UUU', 'UUC', 'UUA', 'UUG', 'UCU', 'UCC', 'UCA', 'UCG',
         'UAU', 'UAC', 'UAA', 'UAG', 'UGU', 'UGC', 'UGA', 'UGG',
         'CUU', 'CUC', 'CUA', 'CUG', 'CCU', 'CCC', 'CCA', 'CCG',
         'CAU', 'CAC', 'CAA', 'CAG', 'CGU', 'CGC', 'CGA', 'CGG',
         'AUU', 'AUC', 'AUA', 'AUG', 'ACU', 'ACC', 'ACA', 'ACG',
         'AAU', 'AAC', 'AAA', 'AAG', 'AGU', 'AGC', 'AGA', 'AGG',
         'GUU', 'GUC', 'GUA', 'GUG', 'GCU', 'GCC', 'GCA', 'GCG',
         'GAU', 'GAC', 'GAA', 'GAG', 'GGU', 'GGC', 'GGA', 'GGG')

#Create a vector of amino acids
aminoAcid = c('Phe', 'Phe', 'Leu', 'Leu', 'Ser', 'Ser', 'Ser', 'Ser',
             'Tyr', 'Tyr', 'Stop', 'Stop', 'Cys', 'Cys', 'Stop', 'Trp',
             'Leu', 'Leu', 'Leu', 'Leu', 'Pro', 'Pro', 'Pro', 'Pro',
             'His', 'His', 'Gln', 'Gln', 'Arg', 'Arg', 'Arg', 'Arg',
             'Ile', 'Ile', 'Ile', 'Met', 'Thr', 'Thr', 'Thr', 'Thr',
             'Asn', 'Asn', 'Lys', 'Lys', 'Ser', 'Ser', 'Arg', 'Arg',
             'Val', 'Val', 'Val', 'Val', 'Ala', 'Ala', 'Ala', 'Ala',
             'Asp', 'Asp', 'Glu', 'Glu', 'Gly', 'Gly', 'Gly', 'Gly')

#Create an array
geneticCode = array(c(codon, aminoAcid), dim = c(8, 8, 2))
print(geneticCode) #show the genetic code table
geneticCode[1,1,] #select all values from the first row and column
, , 1

     [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8] 
[1,] "UUU" "UAU" "CUU" "CAU" "AUU" "AAU" "GUU" "GAU"
[2,] "UUC" "UAC" "CUC" "CAC" "AUC" "AAC" "GUC" "GAC"
[3,] "UUA" "UAA" "CUA" "CAA" "AUA" "AAA" "GUA" "GAA"
[4,] "UUG" "UAG" "CUG" "CAG" "AUG" "AAG" "GUG" "GAG"
[5,] "UCU" "UGU" "CCU" "CGU" "ACU" "AGU" "GCU" "GGU"
[6,] "UCC" "UGC" "CCC" "CGC" "ACC" "AGC" "GCC" "GGC"
[7,] "UCA" "UGA" "CCA" "CGA" "ACA" "AGA" "GCA" "GGA"
[8,] "UCG" "UGG" "CCG" "CGG" "ACG" "AGG" "GCG" "GGG"

, , 2

     [,1]  [,2]   [,3]  [,4]  [,5]  [,6]  [,7]  [,8] 
[1,] "Phe" "Tyr"  "Leu" "His" "Ile" "Asn" "Val" "Asp"
[2,] "Phe" "Tyr"  "Leu" "His" "Ile" "Asn" "Val" "Asp"
[3,] "Leu" "Stop" "Leu" "Gln" "Ile" "Lys" "Val" "Glu"
[4,] "Leu" "Stop" "Leu" "Gln" "Met" "Lys" "Val" "Glu"
[5,] "Ser" "Cys"  "Pro" "Arg" "Thr" "Ser" "Ala" "Gly"
[6,] "Ser" "Cys"  "Pro" "Arg" "Thr" "Ser" "Ala" "Gly"
[7,] "Ser" "Stop" "Pro" "Arg" "Thr" "Arg" "Ala" "Gly"
[8,] "Ser" "Trp"  "Pro" "Arg" "Thr" "Arg" "Ala" "Gly"

  1. ดาต้าเฟรม (data frame) คือข้อมูลที่จัดเก็บในลักษณะตาราง (table) มีคอลัม (column) เก็บข้อมูลหรือตัวแปรเดียวกันและแถว (row) ที่เก็บข้อมูลชุดของตัวแปรของแต่ละตัวอย่าง ใช้ฟังก์ชั่น data.frame() ในการสร้างตาราง เช่น สร้าง data frame เพื่อเก็บข้อมูลรหัสพันธุกรรมในตัวอย่างก่อนหน้า เป็นตารางที่มีสองคอลัมและ 64 แถว โดยคอลัมแรกเป็น codon และคอลัมที่สองเป็น amino acid
In [7]:
geneticCodeTable = data.frame(codon, aminoAcid)

#show first few rows of the table
head(geneticCodeTable)

#show last few rows of the table
tail(geneticCodeTable)

#search for an amino acid corresponding to the codon
geneticCodeTable[geneticCodeTable$codon == "UUU",]
codonaminoAcid
UUUPhe
UUCPhe
UUALeu
UUGLeu
UCUSer
UCCSer
codonaminoAcid
59GAAGlu
60GAGGlu
61GGUGly
62GGCGly
63GGAGly
64GGGGly
codonaminoAcid
UUUPhe
codonaminoAcid
UUUPhe
  1. ลิสต์ (list) เป็นอ็อบเจ็คที่สามารถเก็บข้อมูลได้หลายประเภท ไม่ว่าจะเป็น จำนวน ข้อความ เวคเตอร์หรือลิสต์ด้วยกัน สามารถสร้างลิสต์ด้วยฟังก์ชั่น list() และเข้าถึงข้อมูลที่เก็บภภายในลิสต์ด้วย [] หากในลิสต์มีข้อมูลซ้อนหลายชั้น จะสามารถเข้าถึงได้ด้วยการใช้ [[]][] โดยวงเล็บแรก [[]] จะระบุลำดับของข้อมูลชั้นแรก ส่วนวงเล็บถัดมา [] จะระบุลำดับในข้อมูลชั้นที่สอง
In [5]:
#create a list
list_data <- list("Red", "Green", c(21,32,11), TRUE, 51.23, 119.1)
print(list_data) #show list elements

#access the list items
list_data[1]
list_data[[3]][2] #to access the inner list data, second element of the third item

list_data[1] = "black"  #change the first value in the list to "black"
list_data[1]
[[1]]
[1] "Red"

[[2]]
[1] "Green"

[[3]]
[1] 21 32 11

[[4]]
[1] TRUE

[[5]]
[1] 51.23

[[6]]
[1] 119.1

  1. 'Red'
32
  1. 'black'
  1. แฟคเตอร์ (Factor) เป็นอ็อบเจ็คข้อมูลที่เหมาะสำหรับข้อมูลที่เเบ่งเป็นกลุ่มหรือ categories โดยข้อมูลแต่ละค่าที่เก็บในอ็อบเจ็คประเภทนี้จะมีเลเวล (level) กำกับ อ็อบเจ็คชนิดนี้สามารถสร้างด้วยฟังก์ชั่น factor()
In [8]:
#create a vector
data <- c("East","West","East","North","North","East","West","West","West","East","North")

print(data)
print(is.factor(data))

# Apply the factor function.
factor_data <- factor(data)

print(factor_data)
print(is.factor(factor_data))

# Apply the factor function with required order of the level.
new_order_data <- factor(factor_data,levels = c("East","West","North"))
print(new_order_data)

# Create the vectors for data frame.
height <- c(132,151,162,139,166,147,122)
weight <- c(48,49,66,53,67,52,40)
gender <- c("male","male","female","female","male","female","male")

# Create the data frame.
input_data <- data.frame(height,weight,gender)
print(input_data)

# Test if the gender column is a factor.
print(is.factor(input_data$gender))

# Print the gender column so see the levels.
print(input_data$gender)
 [1] "East"  "West"  "East"  "North" "North" "East"  "West"  "West"  "West" 
[10] "East"  "North"
[1] FALSE
 [1] East  West  East  North North East  West  West  West  East  North
Levels: East North West
[1] TRUE
 [1] East  West  East  North North East  West  West  West  East  North
Levels: East West North
  height weight gender
1    132     48   male
2    151     49   male
3    162     66 female
4    139     53 female
5    166     67   male
6    147     52 female
7    122     40   male
[1] TRUE
[1] male   male   female female male   female male  
Levels: female male
  1. สตริง (String) เป็นอ็อบเจ็คที่เก็บข้อมูลที่เป็นตัวอักษรหรือข้อความ จะเก็บอยู่ภายใต้เครื่องหมาย ' ' หรือ " " การดำเนินการกับอ็อบเจ็คประเภทนี้สามารถทำได้หลายวิธีเช่น แสดงผลด้วยฟังก์ชั่น print() และ paste() นับจำนวนตัวอักษรด้วยฟังก์ชั่น nchar() จัดรปแบบด้วยฟังก์ชั่น format() เปลี่ยนเป็นอักษรพิมพ์ใหญ่หรือเล็กด้วยฟังก์ชั่น toupper() และ tolower() ตัดหรือเลือกบางช่วงของข้อความด้วยฟังก์ชั่น substring()
In [11]:
#To create a String
a <- 'Start and end with single quote'
print(a)

b <- "Start and end with double quotes"
print(b)

c <- "single quote ' in between double quotes"
print(c)

d <- 'Double quotes " in between single quote'
print(d)

#display strings by the paste() function
a <- "Hello"
b <- 'How'
c <- "are you? "

print(paste(a,b,c))

print(paste(a,b,c, sep = "-"))

print(paste(a,b,c, sep = "", collapse = ""))

#count the number of characters
result <- nchar("Count the number of characters")
print(result)

# Total number of digits displayed. Last digit rounded off.
result <- format(23.123456789, digits = 9)
print(result)

# Display numbers in scientific notation.
result <- format(c(6, 13.14521), scientific = TRUE)
print(result)

# The minimum number of digits to the right of the decimal point.
result <- format(23.47, nsmall = 5)
print(result)

# Format treats everything as a string.
result <- format(6)
print(result)

# Numbers are padded with blank in the beginning for width.
result <- format(13.7, width = 6)
print(result)

# Left justify strings.
result <- format("Hello", width = 8, justify = "l")
print(result)

# Justfy string with center.
result <- format("Hello", width = 8, justify = "c")
print(result)

# Changing to Upper case.
result <- toupper("Changing To Upper")
print(result)

# Changing to lower case.
result <- tolower("Changing To Lower")
print(result)

#to slice the string
result <- substring("Extract", 5, 7)
print(result)
[1] "Start and end with single quote"
[1] "Start and end with double quotes"
[1] "single quote ' in between double quotes"
[1] "Double quotes \" in between single quote"
[1] "Hello How are you? "
[1] "Hello-How-are you? "
[1] "HelloHoware you? "
[1] 30
[1] "23.1234568"
[1] "6.000000e+00" "1.314521e+01"
[1] "23.47000"
[1] "6"
[1] "  13.7"
[1] "Hello   "
[1] " Hello  "
[1] "CHANGING TO UPPER"
[1] "changing to lower"
[1] "act"

ตัวอย่างการนำข้อมูลมาศึกษาและวิเคราะห์ด้วยภาษา R

ตัวอย่างที่ 1 เป็นข้อมูลจากการศึกษาความสัมพันธ์ของขนาดร่างกาย (body size) และอัตราการเกิดเมทาบอลิซึมของสัตว์ในกลุ่ม Artiodactyla ข้อมูลนี้เก็บในรูปแบบดาต้าเฟรม ท่านคิดว่าสามารถวิเคราะห์ข้อมูลนี้ด้วยวิธีการทางสถิติอย่างไรได้บ้าง ระบุุคำถามหรือสมมติฐาน แล้ววิธีการวิเคราะห์

In [ ]:
size_mr_data <- data.frame(
  body_mass = c(32000, 37800, 347000, 4200, 196500, 100000,
    4290, 32000, 65000, 69125, 9600, 133300, 150000, 407000,
    115000, 67000,325000, 21500, 58588, 65320, 85000, 135000,
    20500, 1613, 1618),
  metabolic_rate = c(49.984, 51.981, 306.770, 10.075, 230.073, 
    148.949, 11.966, 46.414, 123.287, 106.663, 20.619, 180.150, 
    200.830, 224.779, 148.940, 112.430, 286.847, 46.347,
    142.863, 106.670, 119.660, 104.150, 33.165, 4.900, 4.865),
  family = c("Antilocapridae", "Antilocapridae", "Bovidae",
    "Bovidae", "Bovidae", "Bovidae", "Bovidae", "Bovidae",
    "Bovidae", "Bovidae", "Bovidae", "Bovidae", "Bovidae",
    "Camelidae", "Camelidae", "Canidae", "Cervidae",
    "Cervidae", "Cervidae", "Cervidae", "Cervidae", "Suidae",
    "Tayassuidae", "Tragulidae", "Tragulidae"))
size_mr_data

ตัวอย่างที่ 2 เป็นข้อมูลจากการศึกษาปัจจัยที่มีผลต่อขนาด (size) และการสะสมคาร์บอน (carbon storage) ของไม้พุ่ม (shrub) โดยการทดลองทำใน 4 พื้นที่ (location) และศึกษาผลของปัจจัย 3 อย่าง (treatment) คือ experiment 1, 2 และ 3 ท่านคิดว่าสามารถวิเคราะห์ข้อมูลนี้ด้วยวิธีการทางสถิติอย่างไรได้บ้าง ระบุุคำถามหรือสมมติฐาน แล้ววิธีการวิเคราะห์

In [16]:
shrub_volume = data.frame(
    site = c(rep(1, 3), rep(2, 3), rep(3, 3), rep(4, 3)),
    experiment = c(rep(1:3, 4)),
    length = c(2.2, 2.1, 2.7, 3, 3.1, 2.5, 1.9, 1.1, 3.5, 2.9, 4.5, 1.2),
    width = c(1.3, 2.2, 1.5, 4.5, 3.1, 2.8, 1.8, 0.5, 2, 2.7, 4.8, 1.8),
    height = c(9.6, 7.6, 2.2, 1.5, 4, 3, 4.5, 2.3, 7.5, 3.2, 6.5, 2.7)
)

rep(1,3)
shrub_volume
  1. 1
  2. 1
  3. 1
siteexperimentlengthwidthheight
1 1 2.21.39.6
1 2 2.12.27.6
1 3 2.71.52.2
2 1 3.04.51.5
2 2 3.13.14.0
2 3 2.52.83.0
3 1 1.91.84.5
3 2 1.10.52.3
3 3 3.52.07.5
4 1 2.92.73.2
4 2 4.54.86.5
4 3 1.21.82.7
In [ ]: