ฟังก์ชั่นในการเขียนโปรแกรม R พร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

ฟังก์ชันในแพ็กเกจ R รวบรวมชุดคำสั่งไว้ภายใต้ชื่อเดียว ดังนั้นงานที่ทำซ้ำๆ จึงสามารถเรียกใช้งานได้เพียงครั้งเดียว ประกอบด้วยตัวช่วยทางคณิตศาสตร์และสถิติในตัว ฟังก์ชันที่ผู้ใช้กำหนดเอง และขอบเขตของสภาพแวดล้อมpingและในส่วนนี้จะกล่าวถึงการใช้ข้อโต้แย้งแบบมีเงื่อนไข พร้อมตัวอย่างประกอบ

  • 🔘 กายวิภาคศาสตร์เชิงหน้าที่: ฟังก์ชันประกอบด้วยชื่อ รายการอาร์กิวเมนต์ที่ไม่บังคับ เนื้อหา และค่าส่งคืนที่ไม่บังคับ
  • 🧮 ความคุ้มครองในตัว: R มีฟังก์ชันช่วยเหลือทั่วไป เช่น diff() และ length() รวมถึงฟังก์ชันทางคณิตศาสตร์และสถิติต่างๆ ด้วย
  • 📐 การปรับขนาดที่สามารถนำกลับมาใช้ใหม่ได้: ฟังก์ชัน normalize() จะแปลงบล็อกการปรับขนาดแบบคัดลอกและวางให้เป็นการเรียกใช้งานซ้ำได้เพียงครั้งเดียว
  • 🧭 กฎระเบียบด้านสิ่งแวดล้อม: ทุกครั้งที่มีการเรียกใช้ฟังก์ชัน จะเป็นการเปิดสภาพแวดล้อมภายใน และ R จะทำการแปลงชื่อจากคำจำกัดความภายในสุดไปยังคำจำกัดความภายนอก
  • 🧪 ลอจิกแบบมีเงื่อนไข: เงื่อนไข if/else ภายในฟังก์ชัน split_data() จะส่งคืนชุดข้อมูลฝึกฝนหรือชุดข้อมูลทดสอบอย่างใดอย่างหนึ่ง
  • 🛠️ หลักเกณฑ์การตั้งชื่อ: การตั้งชื่อฟังก์ชันที่ผู้ใช้กำหนดเองให้แตกต่างจากฟังก์ชันในตัวจะช่วยหลีกเลี่ยงการบดบังและข้อผิดพลาดที่ทำให้เกิดความสับสน

ฟังก์ชั่นในการเขียนโปรแกรม R

ฟังก์ชั่นใน R คืออะไร?

A ฟังก์ชันในสภาพแวดล้อมการเขียนโปรแกรมคือชุดคำสั่ง โปรแกรมเมอร์สร้างฟังก์ชันที่ควรหลีกเลี่ยง การทำซ้ำงานเดิมหรือลดลง ความซับซ้อน.

ฟังก์ชันควรจะเป็น

  • เขียนขึ้นเพื่อปฏิบัติงานที่ระบุไว้
  • อาจมีหรือไม่มีข้อโต้แย้งก็ได้
  • มีร่างกาย
  • อาจส่งคืนค่าหนึ่งค่าหรือมากกว่านั้นหรือไม่ก็ได้

วิธีการทั่วไปสำหรับฟังก์ชันคือการใช้ส่วนอาร์กิวเมนต์เป็น ปัจจัยการผลิต, ให้อาหาร ร่างกาย ส่วนหนึ่งและในที่สุดก็กลับมา เอาท์พุตโครงสร้างของฟังก์ชันเป็นดังต่อไปนี้:

function (arglist)  {
  #Function body
}

R ฟังก์ชั่นในตัวที่สำคัญ

มีฟังก์ชันในตัวมากมายใน R โดย R จะจับคู่พารามิเตอร์อินพุตของคุณกับอาร์กิวเมนต์ของฟังก์ชัน ไม่ว่าจะตามค่าหรือตามตำแหน่ง จากนั้นจึงดำเนินการกับเนื้อหาของฟังก์ชัน อาร์กิวเมนต์ของฟังก์ชันสามารถมีค่าเริ่มต้นได้: หากคุณไม่ได้ระบุอาร์กิวเมนต์เหล่านี้ R จะใช้ค่าเริ่มต้น
หมายเหตุ:
คุณสามารถดูซอร์สโค้ดของฟังก์ชันได้โดยการเรียกใช้ชื่อของฟังก์ชันนั้นในคอนโซล

Typing ชื่อฟังก์ชันที่ไม่มีวงเล็บจะแสดงซอร์สโค้ดของฟังก์ชันนั้น ดังที่แสดงในคอนโซลด้านล่าง

คอนโซล R แสดงรหัสต้นฉบับของฟังก์ชันในตัว

เราจะเห็นการทำงานสามกลุ่ม

  • ฟังก์ชั่นทั่วไป
  • ฟังก์ชันคณิตศาสตร์
  • ฟังก์ชันทางสถิติ

ฟังก์ชั่นทั่วไป

เราคุ้นเคยกับฟังก์ชันทั่วไป เช่น cbind(), rbind(), range() อยู่แล้ว เรียงลำดับ ()และ order() ฟังก์ชันเหล่านี้แต่ละฟังก์ชันมีหน้าที่เฉพาะ รับอาร์กิวเมนต์เพื่อส่งคืนผลลัพธ์ ต่อไปนี้คือฟังก์ชันสำคัญที่ควรรู้:

ฟังก์ชันต่าง()

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

หมายเหตุเรามักต้องการสร้างข้อมูลสุ่ม แต่เพื่อการเรียนรู้และการเปรียบเทียบ เราต้องการให้ตัวเลขเหล่านั้นเหมือนกันในทุกเครื่อง เพื่อให้แน่ใจว่าทุกเครื่องสร้างข้อมูลเดียวกัน เราจึงใช้ฟังก์ชัน set.seed() ด้วยค่าสุ่ม 123 ฟังก์ชัน set.seed() จะกำหนดจุดเริ่มต้นของตัวสร้างเลขสุ่มเทียม ดังนั้นทุกเครื่องจึงสร้างลำดับเดียวกัน หากไม่มี set.seed() แต่ละรอบการทำงานจะส่งคืนลำดับที่แตกต่างกัน

set.seed(123)
## Create the data
x = rnorm(1000)
ts <- cumsum(x)
## Stationary the serie
diff_ts <- diff(ts)
par(mfrow=c(1,2))
## Plot the series
plot(ts, type='l')
plot(diff(ts), type='l')

แผงภาพสองแผงด้านล่างแสดงอนุกรมสะสมดั้งเดิมควบคู่ไปกับอนุกรมผลต่าง ซึ่งในที่นี้จะผันผวนรอบค่าเฉลี่ยคงที่

อนุกรมสะสมดั้งเดิมที่อยู่ถัดจากอนุกรมคงที่ที่หาผลต่างแล้ว

ความยาว () ฟังก์ชัน

ในหลายกรณี เราต้องการทราบความยาวของเวกเตอร์เพื่อใช้ในการคำนวณหรือใช้ในลูป for ฟังก์ชัน length() จะนับจำนวนแถวในเวกเตอร์ x โค้ดต่อไปนี้จะนำเข้าชุดข้อมูล cars และส่งคืนจำนวนแถว

หมายเหตุฟังก์ชัน `length()` จะคืนค่าจำนวนองค์ประกอบในเวกเตอร์ หากฟังก์ชันนี้ถูกส่งผ่านเข้าไปใน เมทริกซ์ หรือหากเป็น data frame ระบบจะส่งคืนจำนวนคอลัมน์

dt <- cars
## number columns
length(dt)

Output:

## [1] 1
## number rows
length(dt[,1])

Output:

## [1] 50

ฟังก์ชันทางคณิตศาสตร์

นอกเหนือจากฟังก์ชันช่วยเหลือทั่วไปแล้ว R ยังมีฟังก์ชันทางคณิตศาสตร์มากมายที่ทำงานกับแต่ละองค์ประกอบของเวกเตอร์

OperaTor Descriptไอออน
เอบีเอส (x) รับค่าสัมบูรณ์ของ x
บันทึก(x,ฐาน=y) รับลอการิทึมของ x พร้อมฐาน y ถ้าไม่ได้ระบุฐาน จะส่งกลับค่าลอการิทึมธรรมชาติ
ประสบการณ์(x) ส่งกลับเลขชี้กำลังของ x
sqrt (x) ส่งคืนค่ารากที่สองของ x
แฟกทอเรียล(x) ส่งกลับค่าแฟกทอเรียลของ x (x!)
# sequence of number from 44 to 55 both including incremented by 1
x_vector <- seq(45,55, by = 1)
#logarithm
log(x_vector)

Output:

##  [1] 3.806662 3.828641 3.850148 3.871201 3.891820 3.912023 3.931826
##  [8] 3.951244 3.970292 3.988984 4.007333
#exponential
exp(x_vector)
#squared root
sqrt(x_vector)

Output:

##  [1] 6.708204 6.782330 6.855655 6.928203 7.000000 7.071068 7.141428
##  [8] 7.211103 7.280110 7.348469 7.416198
#factorial
factorial(x_vector)

Output:

##  [1] 1.196222e+56 5.502622e+57 2.586232e+59 1.241392e+61 6.082819e+62
##  [6] 3.041409e+64 1.551119e+66 8.065818e+67 4.274883e+69 2.308437e+71
## [11] 1.269640e+73

ฟังก์ชันทางสถิติ

ฟังก์ชันทางคณิตศาสตร์ใช้ในการแปลงค่า ในขณะที่ฟังก์ชันทางสถิติใช้ในการสรุปค่า R มีฟังก์ชันทางสถิติหลากหลายประเภทติดตั้งมาในโปรแกรมมาตรฐาน ในบทความนี้ เราจะมาดูฟังก์ชันที่สำคัญที่สุดโดยสังเขป

ฟังก์ชันทางสถิติพื้นฐาน

OperaTor Descriptไอออน
ค่าเฉลี่ย(x) ค่าเฉลี่ยของ x
ค่ามัธยฐาน(x) ค่ามัธยฐานของ x
วาร์(x) ความแปรปรวนของ x
เอสดี(x) ค่าเบี่ยงเบนมาตรฐานของ x
ขนาด(x) คะแนนมาตรฐาน (z-score) ของ x
ปริมาณ(x) ควอไทล์ของ x
สรุป(x) สรุป x: ค่าเฉลี่ย, ต่ำสุด, สูงสุด ฯลฯ
speed <- dt$speed
speed
# Mean speed of cars dataset
mean(speed)

Output:

## [1] 15.4
# Median speed of cars dataset
median(speed)

Output:

## [1] 15
# Variance speed of cars dataset
var(speed)

Output:

## [1] 27.95918
# Standard deviation speed of cars dataset
sd(speed)

Output:

## [1] 5.287644
# Standardize vector speed of cars dataset		
head(scale(speed), 5)

Output:

##           [,1]
## [1,] -2.155969
## [2,] -2.155969
## [3,] -1.588609
## [4,] -1.588609
## [5,] -1.399489
# Quantile speed of cars dataset
quantile(speed)

Output:

##   0%  25%  50%  75% 100%
##    4   12   15   19   25
# Summary speed of cars dataset
summary(speed)

Output:

##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
##     4.0    12.0    15.0    15.4    19.0    25.0

จนถึงจุดนี้ เราได้เรียนรู้ฟังก์ชัน R ในตัวมากมายแล้ว

หมายเหตุระวังด้วยนะ คลาสของอาร์กิวเมนต์เช่น ตัวเลข ค่าบูลีน หรือสตริง ตัวอย่างเช่น หากเราต้องการส่งค่าสตริง เราต้องใส่เครื่องหมายอัญประกาศครอบสตริงนั้นไว้ เช่น “ABC”

เขียนฟังก์ชันใน R

ในบางโอกาส เราจำเป็นต้องเขียนฟังก์ชันของเราเอง เนื่องจากเราต้องทำงานบางอย่างให้สำเร็จ และไม่มีฟังก์ชันสำเร็จรูปอยู่ ฟังก์ชันที่ผู้ใช้กำหนดเองนั้นเกี่ยวข้องกับ... พร้อมชื่อ, ข้อโต้แย้ง และ ร่างกาย.

function.name <- function(arguments) 
{
    computations on the arguments	
    some other code
}		

หมายเหตุ: แนวปฏิบัติที่ดีคือการตั้งชื่อฟังก์ชันที่ผู้ใช้กำหนดแตกต่างจากฟังก์ชันในตัว มันหลีกเลี่ยงความสับสน

ฟังก์ชันอาร์กิวเมนต์หนึ่งรายการ

ในตัวอย่างถัดไป เราจะกำหนดฟังก์ชันกำลังสองอย่างง่าย ฟังก์ชันยอมรับค่าและส่งคืนค่ากำลังสองของค่า

square_function<- function(n) 
{
  # compute the square of integer `n`
  n^2
}  
# calling the function and passing value 4
square_function(4)

Code คำอธิบาย

  • ฟังก์ชันนี้มีชื่อว่า square_function; จะเรียกว่าอะไรก็ได้ที่เราต้องการ
  • ได้รับการโต้แย้ง "n" เรา ไม่ได้ระบุประเภทของตัวแปรเพื่อให้ผู้ใช้สามารถส่งผ่านจำนวนเต็ม เวกเตอร์ หรือเมทริกซ์ได้
  • ฟังก์ชันรับอินพุต “n” และส่งกลับค่ากำลังสองของอินพุต เมื่อคุณใช้ฟังก์ชันนี้เสร็จแล้ว เราสามารถลบมันออกได้ด้วยฟังก์ชัน rm()

# หลังจากที่คุณสร้างฟังก์ชันแล้ว

rm(square_function)
square_function

บนคอนโซล เราจะเห็นข้อความแสดงข้อผิดพลาด :Error: object 'square_function' not found บอกว่าไม่มีฟังก์ชันอยู่

สิ่งแวดล้อมping

ใน R สิ่งแวดล้อม คือกลุ่มของวัตถุต่างๆ เช่น ฟังก์ชัน ตัวแปร เฟรมข้อมูล เป็นต้น

R จะเปิดสภาพแวดล้อมขึ้นทุกครั้งที่เริ่มต้นใช้งาน RStudio

สภาพแวดล้อมระดับบนสุดที่มีอยู่คือ สิ่งแวดล้อมโลกเรียกว่า R_GlobalEnv และเราก็มี สิ่งแวดล้อมท้องถิ่น.

เราสามารถแสดงรายการเนื้อหาของสภาพแวดล้อมปัจจุบันได้

ls(environment())

เอาท์พุต

## [1] "diff_ts"         "dt"              "speed"           "square_function"
## [5] "ts"              "x"               "x_vector"

คุณสามารถดูตัวแปรและฟังก์ชันทั้งหมดที่สร้างขึ้นใน R_GlobalEnv

รายการข้างต้นจะแตกต่างกันไปสำหรับคุณ ขึ้นอยู่กับโค้ดเก่าที่คุณรันใน RStudio

โปรดทราบว่า nอาร์กิวเมนต์ของฟังก์ชัน square_function ไม่ได้อยู่ในสภาพแวดล้อมส่วนกลางนี้

มีการสร้างสภาพแวดล้อมใหม่สำหรับแต่ละฟังก์ชัน ในตัวอย่างข้างต้น ฟังก์ชัน square_function() สร้างสภาพแวดล้อมใหม่ภายใน สิ่งแวดล้อมโลก.

เพื่อชี้แจงความแตกต่างระหว่าง ทั่วโลก และ ในประเทศ ในด้านสิ่งแวดเว้นล้อม ลองมาศึกษาตัวอย่างต่อไปนี้กัน

ฟังก์ชันเหล่านี้รับค่า x เป็นอาร์กิวเมนต์และเพิ่มลงใน y กำหนดภายนอกและภายในฟังก์ชัน

ฟังก์ชัน f ใช้ตัวแปร y ที่กำหนดไว้ในสภาพแวดล้อมส่วนกลาง

ฟังก์ชัน f ส่งกลับเอาต์พุต 15 เนื่องจาก y ถูกกำหนดไว้ในสภาพแวดล้อมโกลบอล ตัวแปรใดๆ ที่กำหนดไว้ในสภาพแวดล้อมส่วนกลางสามารถใช้ได้ภายในเครื่อง ตัวแปร y มีค่าเป็น 10 ในระหว่างการเรียกใช้ฟังก์ชันทั้งหมด และสามารถเข้าถึงได้ตลอดเวลา

เรามาดูกันว่าเกิดอะไรขึ้นถ้าตัวแปร y ถูกกำหนดไว้ภายในฟังก์ชัน

เราจำเป็นต้องปล่อย `y` ก่อนที่จะรันโค้ดนี้โดยใช้ rm r

ฟังก์ชัน f กำหนดค่า y ภายในสภาพแวดล้อมภายในของตัวเอง

ผลลัพธ์จะเป็น 15 เช่นกันเมื่อเราเรียก f(5) แต่ส่งคืนข้อผิดพลาดเมื่อเราพยายามพิมพ์ค่า y ตัวแปร y ไม่ได้อยู่ในสภาพแวดล้อมโกลบอล

ในที่สุด R จะใช้คำจำกัดความของตัวแปรล่าสุดเพื่อส่งผ่านภายในเนื้อหาของฟังก์ชัน มาพิจารณาตัวอย่างต่อไปนี้:

R ใช้การนิยามภายในสุดของ y ภายในตัวฟังก์ชัน

R ละเว้นค่า y ที่กำหนดไว้นอกฟังก์ชันเนื่องจากเราสร้างตัวแปร ay ไว้อย่างชัดเจนภายในเนื้อหาของฟังก์ชัน

ฟังก์ชันหลายข้อโต้แย้ง

เราสามารถเขียนฟังก์ชันที่มีมากกว่าหนึ่งอาร์กิวเมนต์ได้ พิจารณาฟังก์ชันที่เรียกว่า "เวลา" เป็นฟังก์ชันตรงไปตรงมาคูณตัวแปรสองตัว

times <- function(x,y) {
  x*y
	}
times(2,4)

Output:

## [1] 8

เมื่อใดที่เราควรเขียนฟังก์ชัน?

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

สูตรเพื่อทำให้ตัวแปรเป็นมาตรฐาน

เรารู้วิธีใช้ฟังก์ชัน min() และ max() ใน R แล้ว เราใช้ไลบรารี tibble เพื่อสร้าง data frame Tibble เป็นฟังก์ชันที่สะดวกที่สุดในการสร้างชุดข้อมูลตั้งแต่เริ่มต้น

library(tibble)
# Create a data frame
data_frame <- tibble(  
  c1 = rnorm(50, 5, 1.5), 
  c2 = rnorm(50, 5, 1.5),    
  c3 = rnorm(50, 5, 1.5),    
)

เราจะดำเนินการคำนวณฟังก์ชันที่อธิบายไว้ข้างต้นเป็นสองขั้นตอน ในขั้นตอนแรก เราจะสร้างตัวแปรชื่อ c1_norm ซึ่งเป็นการปรับขนาดของ c1 ในขั้นตอนที่สอง เราเพียงแค่คัดลอกและวางโค้ดของ c1_norm แล้วเปลี่ยนเป็น c2 และ c3

รายละเอียดของฟังก์ชันที่มีคอลัมน์ c1:

ผู้เสนอชื่อ: : data_frame$c1 -min(data_frame$c1))

ตัวส่วน: สูงสุด(data_frame$c1)-นาที(data_frame$c1))

ดังนั้นเราจึงสามารถแบ่งพวกมันเพื่อให้ได้ค่ามาตรฐานของคอลัมน์ c1:

(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

เราสามารถสร้าง c1_norm, c2_norm และ c3_norm:

Create c1_norm: rescaling of c1		
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
# show the first five values
head(data_frame$c1_norm, 5)

Output:

## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991

มันได้ผล. เราสามารถคัดลอกและวางได้

data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

จากนั้นเปลี่ยน c1_norm เป็น c2_norm และ c1 เป็น c2 เราทำเช่นเดียวกันเพื่อสร้าง c3_norm

data_frame$c2_norm <- (data_frame$c2 - min(data_frame$c2))/(max(data_frame$c2)-min(data_frame$c2))
data_frame$c3_norm <- (data_frame$c3 - min(data_frame$c3))/(max(data_frame$c3)-min(data_frame$c3))

เราปรับขนาดตัวแปร c1, c2 และ c3 ได้อย่างสมบูรณ์แบบ

อย่างไรก็ตาม วิธีนี้มีโอกาสเกิดข้อผิดพลาดได้ เราอาจคัดลอกแล้วลืมเปลี่ยนชื่อคอลัมน์หลังจากวาง ดังนั้น วิธีปฏิบัติที่ดีคือการเขียนฟังก์ชันทุกครั้งที่คุณต้องการวางโค้ดเดียวกันมากกว่าสองครั้ง เราสามารถจัดเรียงโค้ดใหม่เป็นสูตรและเรียกใช้เมื่อใดก็ตามที่ต้องการ ในการเขียนฟังก์ชันของเราเอง เราต้องระบุ:

  • ชื่อ: normalize.
  • จำนวนอาร์กิวเมนต์: เราต้องการเพียงอาร์กิวเมนต์เดียวเท่านั้น ซึ่งเป็นคอลัมน์ที่เราใช้ในการคำนวณ
  • ร่างกาย: นี่เป็นเพียงสูตรที่เราต้องการคืน

เราจะดำเนินการทีละขั้นตอนเพื่อสร้างฟังก์ชันที่ทำให้เป็นมาตรฐาน

ขั้นตอน 1) เราสร้างตัวเศษ ซึ่งก็คือ x – min(x) ใน R เราสามารถเก็บตัวเศษไว้ในตัวแปรได้ดังนี้:

nominator <- x-min(x)

ขั้นตอน 2) เราคำนวณตัวหาร: max(x) – min(x) เราสามารถทำซ้ำแนวคิดของขั้นตอนที่ 1 และเก็บผลการคำนวณไว้ในตัวแปรได้:

denominator <- max(x)-min(x)

ขั้นตอน 3) เราทำการหารระหว่างตัวเสนอชื่อและตัวส่วน

normalize <- nominator/denominator

ขั้นตอน 4) ในการคืนค่าให้กับฟังก์ชันที่เรียกใช้ เราต้องผ่านการทำให้เป็นมาตรฐานภายใน return() เพื่อรับเอาต์พุตของฟังก์ชัน

return(normalize)

ขั้นตอน 5) เราพร้อมที่จะใช้ฟังก์ชันโดยการห่อหุ้มแล้วping ทุกอย่างที่อยู่ภายในวงเล็บ

normalize <- function(x){
  # step 1: create the nominator
  nominator <- x-min(x)
  # step 2: create the denominator
  denominator <- max(x)-min(x)
  # step 3: divide nominator by denominator
  normalize <- nominator/denominator
  # return the value
  return(normalize)
}

มาทดสอบฟังก์ชันของเรากับตัวแปร c1:

normalize(data_frame$c1)

มันทำงานได้อย่างสมบูรณ์แบบ เราสร้างฟังก์ชันแรกของเรา

ฟังก์ชันเป็นวิธีการที่ครอบคลุมมากกว่าในการทำงานซ้ำๆ เราสามารถใช้สูตร normalize กับคอลัมน์ต่างๆ ได้ดังตัวอย่างด้านล่าง:

data_frame$c1_norm_function <- normalize (data_frame$c1)
data_frame$c2_norm_function <- normalize	(data_frame$c2)
data_frame$c3_norm_function <- normalize	(data_frame$c3)

แม้ว่าตัวอย่างจะเรียบง่าย แต่เราก็สามารถเข้าใจถึงพลังของสูตรได้ โค้ดข้างต้นอ่านง่ายกว่าและหลีกเลี่ยงข้อผิดพลาดที่เกิดจากการคัดลอกโค้ด

ฟังก์ชั่นมีเงื่อนไข

ฟังก์ชัน normalize() ทำงานเหมือนเดิมเสมอ บางครั้ง เราอาจต้องใส่เงื่อนไขเข้าไปในฟังก์ชันเพื่อให้โค้ดส่งผลลัพธ์ที่แตกต่างกันออกไป

ในงาน Machine Learning เราจำเป็นต้องแบ่งชุดข้อมูลระหว่างชุดรถไฟและชุดทดสอบ ชุดรถไฟอนุญาตให้อัลกอริธึมเรียนรู้จากข้อมูล เพื่อทดสอบประสิทธิภาพของโมเดลของเรา เราสามารถใช้ชุดทดสอบเพื่อส่งคืนการวัดประสิทธิภาพ R ไม่มีฟังก์ชันในการสร้างชุดข้อมูลสองชุด เราสามารถเขียนฟังก์ชันของเราเองเพื่อทำสิ่งนั้นได้ ฟังก์ชันของเรารับอาร์กิวเมนต์สองตัวและเรียกว่า split_data() แนวคิดเบื้องหลังนั้นเรียบง่าย เราคูณความยาวของชุดข้อมูล (เช่น จำนวนการสังเกต) ด้วย 0.8 ตัวอย่างเช่น หากเราต้องการแยกชุดข้อมูล 80/20 และชุดข้อมูลของเรามี 100 แถว ฟังก์ชันของเราจะคูณ 0.8*100 = 80 โดยจะมีการเลือก 80 แถวให้เป็นข้อมูลการฝึกของเรา

เราจะใช้ชุดข้อมูลคุณภาพอากาศเพื่อทดสอบฟังก์ชันที่ผู้ใช้กำหนด ชุดข้อมูลคุณภาพอากาศมี 153 แถว เราสามารถดูได้ด้วยรหัสด้านล่าง:

nrow(airquality)

Output:

## [1] 153

เราจะดำเนินการดังนี้:

split_data <- function(df, train = TRUE)
Arguments:
-df: Define the dataset
-train: Specify if the function returns the train set or test set. By default, set to TRUE

ฟังก์ชันของเรามีอาร์กิวเมนต์สองตัว อาร์กิวเมนต์ train เป็นพารามิเตอร์บูลีน ถ้าตั้งค่าเป็น TRUE ฟังก์ชันของเราจะสร้างชุดข้อมูลการฝึก มิฉะนั้น ฟังก์ชันจะสร้างชุดข้อมูลการทดสอบ

เราสามารถดำเนินการต่อได้เช่นเดียวกับฟังก์ชัน normalize() เราเขียนโค้ดราวกับว่าเป็นโค้ดที่ใช้เพียงครั้งเดียว จากนั้นจึงห่อทุกอย่างที่มีเงื่อนไขไว้ในส่วนเนื้อหาเพื่อสร้างฟังก์ชัน

ขั้นตอนที่ 1:

เราจำเป็นต้องคำนวณความยาวของชุดข้อมูล ทำได้โดยใช้ฟังก์ชัน nrow() Nrow ส่งคืนจำนวนแถวทั้งหมดในชุดข้อมูล เราเรียกความยาวผันแปร

length<- nrow(airquality)
length

Output:

## [1] 153

ขั้นตอนที่ 2:

เราคูณความยาวด้วย 0.8 มันจะส่งคืนจำนวนแถวที่เลือก ควรเป็น 153*0.8 = 122.4

total_row <- length*0.8
total_row

Output:

## [1] 122.4

เราต้องการเลือก 122 แถวจาก 153 แถวในชุดข้อมูลคุณภาพอากาศ เราสร้างรายการที่มีค่าตั้งแต่ 1 ถึง Total_row เราเก็บผลลัพธ์ไว้ในตัวแปรที่เรียกว่า split

split <- 1:total_row
split[1:5]

Output:

## [1] 1 2 3 4 5

split เลือก 122 แถวแรกจากชุดข้อมูล ตัวอย่างเช่น เราจะเห็นว่าการแยกตัวแปรของเรารวบรวมค่า 1, 2, 3, 4, 5 และอื่นๆ ค่าเหล่านี้จะเป็นดัชนีเมื่อเราจะเลือกแถวที่จะส่งคืน

ขั้นตอนที่ 3:

เราจำเป็นต้องเลือกแถวในชุดข้อมูลคุณภาพอากาศตามค่าที่เก็บไว้ในตัวแปรแยก ทำเช่นนี้:

train_df <- airquality[split, ] 
head(train_df)

Output:

##[1]    Ozone Solar.R Wind Temp Month Day
##[2]  51    13     137 10.3   76     6  20
##[3]  15    18      65 13.2   58     5  15
##[4]  64    32     236  9.2   81     7   3
##[5]  27    NA      NA  8.0   57     5  27
##[6]  58    NA      47 10.3   73     6  27
##[7]  44    23     148  8.0   82     6  13

ขั้นตอนที่ 4:

เราสามารถสร้างชุดข้อมูลทดสอบได้โดยใช้แถวที่เหลือ 123:153 ทำได้โดยใช้ – หน้าแยก

test_df <- airquality[-split, ] 
head(test_df)

Output:

##[1] Ozone Solar.R Wind Temp Month Day
##[2]  123    85     188  6.3   94     8  31
##[3]  124    96     167  6.9   91     9   1
##[4]  125    78     197  5.1   92     9   2
##[5]  126    73     183  2.8   93     9   3
##[6]  127    91     189  4.6   93     9   4
##[7]  128    47      95  7.4   87     9   5

ขั้นตอนที่ 5:

เราสามารถสร้างเงื่อนไขภายในเนื้อหาของฟังก์ชันได้ โปรดจำไว้ว่า เรามีรถไฟอาร์กิวเมนต์ที่เป็นบูลีนที่ตั้งค่าเป็น TRUE โดยค่าเริ่มต้นเพื่อส่งคืนชุดรถไฟ ในการสร้างเงื่อนไข เราใช้ไวยากรณ์ if:

  if (train ==TRUE){ 
    train_df <- airquality[split, ] 
      return(train)		
  } else {
    test_df <- airquality[-split, ] 
      return(test)		
  }

เท่านี้เราก็สามารถเขียนฟังก์ชันได้ เราจำเป็นต้องเปลี่ยนคุณภาพอากาศเป็น df เท่านั้น เพราะเราต้องการลองใช้ฟังก์ชันของเราเป็นค่าใดๆ กรอบข้อมูลไม่เพียงแต่คุณภาพอากาศ:

split_data <- function(df, train = TRUE){
  length<- nrow(df)
  total_row <- length *0.8
  split <- 1:total_row
  if (train ==TRUE){ 
    train_df <- df[split, ] 
      return(train_df)		
  } else {
    test_df <- df[-split, ] 
      return(test_df)		
  }
}

ลองใช้ฟังก์ชันของเรากับชุดข้อมูลคุณภาพอากาศกันดู เราควรจะมีชุดข้อมูลฝึกฝน 1 ชุดที่มี 122 แถว และชุดข้อมูลทดสอบ 31 แถว

train <- split_data(airquality, train = TRUE)
dim(train)

Output:

## [1] 122   6
test <- split_data(airquality, train = FALSE)
dim(test)

Output:

## [1] 31  6

คำถามที่พบบ่อย

กำหนดค่าในคำนิยาม เช่น function(df, train = TRUE) หากผู้เรียกใช้ละเว้นอาร์กิวเมนต์นั้น R จะใช้ค่าเริ่มต้น ค่าเริ่มต้นจะถูกประเมินแบบไม่ทันที ดังนั้นค่าเริ่มต้นหนึ่งอาจอ้างอิงถึงอาร์กิวเมนต์อื่นของฟังก์ชันเดียวกันก็ได้

ใช่ ฟังก์ชันสามารถเรียกตัวเองได้ตราบใดที่ยังมีคำสั่งหยุดอยู่ping เงื่อนไขจะสิ้นสุดการทำงานของฟังก์ชันแบบวนซ้ำ เช่น ฟังก์ชันแฟกทอเรียลที่คืนค่า 1 เมื่อ n ถึง 1 การวนซ้ำแบบลึกอาจติดขีดจำกัดการซ้อนของนิพจน์ ดังนั้นการวนซ้ำจึงมักปลอดภัยกว่า

ไม่ R จะส่งคืนค่าของนิพจน์ที่ประเมินครั้งล่าสุดโดยอัตโนมัติ ซึ่งเป็นเหตุผลว่าทำไม square_function() จึงทำงานได้โดยไม่ต้องใช้ return() ควรใช้ return() เมื่อต้องการออกจากฟังก์ชันก่อนกำหนด หรือเมื่อการแสดงผลลัพธ์อย่างชัดเจนทำให้ฟังก์ชันอ่านง่ายขึ้น

R จะจับคู่ตามชื่อที่ตรงกันเป๊ะก่อน จากนั้นจึงจับคู่ตามชื่อบางส่วน และสุดท้ายจึงจับคู่ตามตำแหน่งสำหรับส่วนที่เหลือ การตั้งชื่ออาร์กิวเมนต์อย่างชัดเจน เช่น seq(45, 55, by = 1) จะทำให้การเรียกใช้สามารถอ่านได้ง่ายและปลอดภัยจากการจัดลำดับใหม่โดยไม่ตั้งใจ

ฟังก์ชันที่สร้างขึ้นโดยไม่ได้กำหนดชื่อ มักจะส่งผ่านโดยตรงไปยัง sapply() หรือ lapply() R 4.1 เพิ่มรูปแบบย่อโดยใช้เครื่องหมายแบ็กสแลช ดังนั้น \(x) x^2 จึงทำงานได้เหมือนกับ function(x) x^2 แต่ใช้เวลาพิมพ์น้อยกว่ามากping.

คำจำกัดความใหม่จะซ่อนฟังก์ชันในตัวภายในสภาพแวดล้อมนั้น ดังนั้นการเรียกใช้ length() อาจเรียกใช้เวอร์ชันของคุณแทนที่จะเป็นเวอร์ชันพื้นฐาน ลบสำเนาด้วย rm() หรือเลือกชื่อที่แตกต่างกันตั้งแต่เริ่มต้น

ผู้ช่วย AI จะร่างโครงร่างฟังก์ชันจากข้อความแสดงความคิดเห็นที่เป็นภาษาอังกฤษธรรมดา แนะนำค่าเริ่มต้นของอาร์กิวเมนต์ที่เหมาะสม และสร้างการทดสอบหน่วย ควรทดสอบโค้ดที่สร้างขึ้นกับข้อมูลจริงเสมอ เพราะฟังก์ชัน R ที่ดูสมเหตุสมผลอาจส่งค่าผิดพลาดโดยไม่แสดงข้อผิดพลาดก็ได้

ใช่. RStudio เวอร์ชันเดสก์ท็อป 2023.09.0 และเวอร์ชันที่ใหม่กว่า มีตัวเลือกให้ใช้งาน นักบิน GitHub การบูรณาการ มันจะเติมเต็มส่วนของฟังก์ชันจากความคิดเห็น แต่โปรดตรวจสอบข้อเสนอแนะแต่ละข้อ เนื่องจากมันไม่สามารถมองเห็นข้อมูลของคุณได้

สรุปโพสต์นี้ด้วย: