Các hàm trong lập trình R (với ví dụ)

Hàm trong R là gì?

Một hàm , trong môi trường lập trình, là một tập hợp các lệnh. Lập trình viên xây dựng một hàm để tránh lặp lại cùng một tác vụ hoặc giảm độ phức tạp.

Một chức năng nên được

  • được viết để thực hiện một nhiệm vụ cụ thể
  • có thể có hoặc không bao gồm các đối số
  • chứa một cơ thể
  • có thể có hoặc không trả về một hoặc nhiều giá trị.

Cách tiếp cận chung cho một hàm là sử dụng phần đối số làm đầu vào , cung cấp phần thân và cuối cùng trả về đầu ra . Cú pháp của một hàm như sau:

function (arglist) {#Function body}

Trong hướng dẫn này, chúng ta sẽ học

  • R các chức năng tích hợp quan trọng
  • Chức năng chung
  • Các hàm toán học
  • Chức năng thống kê
  • Viết hàm trong R
  • Khi nào chúng ta nên viết hàm?
  • Các hàm với điều kiện

R các chức năng tích hợp quan trọng

Có rất nhiều hàm tích hợp trong R. R khớp các tham số đầu vào của bạn với các đối số hàm của nó, theo giá trị hoặc theo vị trí, sau đó thực thi thân hàm. Các đối số của hàm có thể có giá trị mặc định: nếu bạn không chỉ định các đối số này, R sẽ nhận giá trị mặc định.

Lưu ý : Có thể xem mã nguồn của một hàm bằng cách chạy chính tên của hàm đó trong bảng điều khiển.

Chúng ta sẽ thấy ba nhóm chức năng đang hoạt động

  • Chức năng chung
  • Hàm toán học
  • Chức năng thống kê

Chức năng chung

Chúng ta đã quen thuộc với các hàm tổng quát như hàm cbind (), rbind (), range (), sort (), order (). Mỗi hàm này có một nhiệm vụ cụ thể, nhận các đối số để trả về một kết quả đầu ra. Sau đây là những chức năng quan trọng mà người ta phải biết-

hàm diff ()

Nếu bạn làm việc theo chuỗi thời gian , bạn cần cố định chuỗi bằng cách lấy các giá trị độ trễ của chúng . Một quá trình cố định cho phép liên tục trung bình, phương sai và tự tương quan theo thời gian. Điều này chủ yếu cải thiện dự đoán của một chuỗi thời gian. Nó có thể được thực hiện dễ dàng với hàm diff (). Chúng ta có thể xây dựng dữ liệu chuỗi thời gian ngẫu nhiên có xu hướng và sau đó sử dụng hàm diff () để cố định chuỗi. Hàm diff () chấp nhận một đối số, một vectơ và trả về sự khác biệt có độ trễ và lặp lại phù hợp.

Lưu ý : Chúng tôi thường cần tạo dữ liệu ngẫu nhiên, nhưng để học và so sánh, chúng tôi muốn các con số giống hệt nhau giữa các máy. Để đảm bảo tất cả chúng ta đều tạo ra cùng một dữ liệu, chúng ta sử dụng hàm set.seed () với các giá trị tùy ý là 123. Hàm set.seed () được tạo thông qua quá trình tạo số giả ngẫu nhiên khiến mọi máy tính hiện đại có cùng một chuỗi trong số các con số. Nếu chúng ta không sử dụng hàm set.seed (), tất cả chúng ta sẽ có một dãy số khác nhau.

set.seed(123)## Create the datax = rnorm(1000)ts <- cumsum(x)## Stationary the seriediff_ts <- diff(ts)par(mfrow=c(1,2))## Plot the seriesplot(ts,)plot(diff(ts),)

hàm length ()

Trong nhiều trường hợp, chúng ta muốn biết độ dài của một vectơ để tính toán hoặc được sử dụng trong vòng lặp for. Hàm length () đếm số hàng trong vectơ x. Các mã sau nhập tập dữ liệu ô tô và trả về số hàng.

Lưu ý : length () trả về số phần tử trong một vectơ. Nếu hàm được chuyển vào ma trận hoặc khung dữ liệu, số cột được trả về.

dt <- cars## number columnslength(dt)

Đầu ra:

## [1] 1
## number rowslength(dt[,1])

Đầu ra:

## [1] 50

Các hàm toán học

R có một mảng các hàm toán học.

Nhà điều hành Sự miêu tả
abs (x) Lấy giá trị tuyệt đối của x
log (x, base = y) Lấy logarit của x với cơ số y; nếu cơ số không được chỉ định, trả về lôgarit tự nhiên
exp (x) Trả về cấp số nhân của x
sqrt (x) Trả về căn bậc hai của x
giai thừa (x) Trả về giai thừa của x (x!)
# sequence of number from 44 to 55 both including incremented by 1x_vector <- seq(45,55, by = 1)#logarithmlog(x_vector)

Đầu ra:

## [1] 3.806662 3.828641 3.850148 3.871201 3.891820 3.912023 3.931826## [8] 3.951244 3.970292 3.988984 4.007333
#exponentialexp(x_vector)
#squared rootsqrt(x_vector)

Đầu ra:

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

Đầu ra:

## [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

Chức năng thống kê

Cài đặt tiêu chuẩn R chứa nhiều chức năng thống kê. Trong hướng dẫn này, chúng ta sẽ xem xét ngắn gọn chức năng quan trọng nhất…

Các hàm thống kê cơ bản

Nhà điều hành

Sự miêu tả

nghĩa là (x)

Trung bình của x

trung vị (x)

Trung vị của x

var (x)

Phương sai của x

sd (x)

Độ lệch chuẩn của x

thang đo (x)

Điểm tiêu chuẩn (điểm z) của x

số lượng tử (x)

Các phần tư của x

tóm tắt (x)

Tóm tắt của x: mean, min, max, v.v…

speed <- dt$speedspeed# Mean speed of cars datasetmean(speed)

Đầu ra:

## [1] 15.4
# Median speed of cars datasetmedian(speed)

Đầu ra:

## [1] 15
# Variance speed of cars datasetvar(speed)

Đầu ra:

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

Đầu ra:

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

Đầu ra:

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

Đầu ra:

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

Đầu ra:

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

Cho đến thời điểm này, chúng ta đã học được rất nhiều hàm tích hợp sẵn của R.

Lưu ý : Hãy cẩn thận với lớp của đối số, tức là số, Boolean hoặc chuỗi. Ví dụ: nếu chúng ta cần chuyển một giá trị chuỗi, chúng ta cần đặt chuỗi đó trong dấu ngoặc kép: "ABC".

Viết hàm trong R

Trong một số trường hợp, chúng ta cần viết hàm của riêng mình vì chúng ta phải hoàn thành một nhiệm vụ cụ thể và không có hàm sẵn sàng nào tồn tại. Một chức năng người dùng định nghĩa liên quan đến một tên , lập luận và một cơ thể .

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

Lưu ý : Một phương pháp hay là đặt tên cho một hàm do người dùng định nghĩa khác với một hàm dựng sẵn. Nó tránh nhầm lẫn.

Một hàm đối số

Trong đoạn mã tiếp theo, chúng tôi xác định một hàm bình phương đơn giản. Hàm chấp nhận một giá trị và trả về bình phương của giá trị.

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

Giải thích mã:

  • Hàm được đặt tên là hàm vuông; nó có thể được gọi là bất cứ điều gì chúng ta muốn.
  • Nó nhận được một đối số "n". Chúng tôi đã không chỉ định loại biến để người dùng có thể chuyển một số nguyên, một vectơ hoặc một ma trận
  • Hàm nhận đầu vào "n" và trả về bình phương của đầu vào.

    Khi bạn sử dụng xong hàm, chúng ta có thể xóa nó bằng hàm rm ().

# sau khi bạn tạo hàm

rm(square_function)square_function

Trên bảng điều khiển, chúng ta có thể thấy thông báo lỗi: Lỗi: không tìm thấy đối tượng 'square_ functions' cho biết hàm không tồn tại.

Xác định phạm vi môi trường

Trong R, môi trường là một tập hợp các đối tượng như hàm, biến, khung dữ liệu, v.v.

R mở một môi trường mỗi khi Rstudio được nhắc.

Môi trường cấp cao nhất có sẵn là môi trường toàn cầu , được gọi là R_GlobalEnv. Và chúng tôi có môi trường địa phương.

Chúng tôi có thể liệt kê nội dung của môi trường hiện tại.

ls(environment())

Đầu ra

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

Bạn có thể xem tất cả các biến và hàm được tạo trong R_GlobalEnv.

Danh sách trên sẽ thay đổi đối với bạn dựa trên mã lịch sử mà bạn thực thi trong R Studio.

Lưu ý rằng n, đối số của hàm square_ functions không có trong môi trường toàn cục này .

Một môi trường mới được tạo cho mỗi chức năng. Trong ví dụ trên, hàm square_ functions () tạo một môi trường mới bên trong môi trường toàn cục.

Để làm rõ sự khác biệt giữa môi trường toàn cầumôi trường địa phương , chúng ta hãy nghiên cứu ví dụ sau

Hàm này nhận một giá trị x làm đối số và thêm nó vào y xác định bên ngoài và bên trong hàm

Hàm f trả về kết quả là 15. Điều này là do y được xác định trong môi trường toàn cục. Bất kỳ biến nào được xác định trong môi trường toàn cục đều có thể được sử dụng cục bộ. Biến y có giá trị là 10 trong tất cả các lần gọi hàm và có thể truy cập bất kỳ lúc nào.

Hãy xem điều gì sẽ xảy ra nếu biến y được xác định bên trong hàm.

Chúng ta cần phải dropp `y` trước khi chạy mã này bằng cách sử dụng rm r

Đầu ra cũng là 15 khi chúng ta gọi f (5) nhưng trả về lỗi khi chúng ta cố gắng in giá trị y. Biến y không nằm trong môi trường toàn cục.

Cuối cùng, R sử dụng định nghĩa biến gần đây nhất để chuyển vào bên trong phần thân của một hàm. Hãy xem xét ví dụ sau:

R bỏ qua các giá trị y được xác định bên ngoài hàm vì chúng ta đã tạo rõ ràng biến ay bên trong phần thân của hàm.

Hàm nhiều đối số

Chúng ta có thể viết một hàm với nhiều hơn một đối số. Hãy xem xét chức năng được gọi là "lần". Nó là một hàm đơn giản nhân hai biến.

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

Đầu ra:

## [1] 8

Khi nào chúng ta nên viết hàm?

Nhà khoa học dữ liệu cần thực hiện nhiều nhiệm vụ lặp đi lặp lại. Hầu hết thời gian, chúng tôi sao chép và dán các đoạn mã lặp đi lặp lại. Ví dụ: chuẩn hóa một biến rất được khuyến khích trước khi chúng tôi chạy thuật toán học máy. Công thức để chuẩn hóa một biến là:

Chúng ta đã biết cách sử dụng hàm min () và max () trong R. Chúng ta sử dụng thư viện tibble để tạo khung dữ liệu. Cho đến nay, Tibble là chức năng thuận tiện nhất để tạo tập dữ liệu từ đầu.

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

Chúng tôi sẽ tiến hành theo hai bước để tính toán hàm được mô tả ở trên. Trong bước đầu tiên, chúng ta sẽ tạo một biến có tên là c1_norm, biến này thay đổi tỷ lệ của c1. Trong bước hai, chúng ta chỉ cần sao chép và dán mã của c1_norm và thay đổi bằng c2 và c3.

Chi tiết về hàm với cột c1:

Người đề cử:: data_frame $ c1 -min (data_frame $ c1))

Mẫu số: max (data_frame $ c1) -min (data_frame $ c1))

Do đó, chúng ta có thể chia chúng để lấy giá trị chuẩn hóa của cột c1:

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

Chúng ta có thể tạo c1_norm, c2_norm và c3_norm:

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

Đầu ra:

## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991

Nó hoạt động. Chúng tôi có thể sao chép và dán

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

sau đó thay đổi c1_norm thành c2_norm và c1 thành c2. Chúng ta làm tương tự để tạo 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))

Chúng tôi đã thay đổi tỷ lệ các biến c1, c2 và c3 một cách hoàn hảo.

Tuy nhiên, phương pháp này dễ bị sai lầm. Chúng tôi có thể sao chép và quên thay đổi tên cột sau khi dán. Do đó, một phương pháp hay là viết một hàm mỗi khi bạn cần dán cùng một đoạn mã nhiều hơn hai lần. Chúng ta có thể sắp xếp lại mã thành một công thức và gọi nó bất cứ khi nào cần. Để viết hàm của riêng chúng ta, chúng ta cần cung cấp:

  • Tên: bình thường hóa.
  • số lượng đối số: Chúng ta chỉ cần một đối số, đó là cột chúng ta sử dụng trong tính toán của mình.
  • Phần thân: đây chỉ đơn giản là công thức mà chúng tôi muốn trả về.

Chúng tôi sẽ tiến hành từng bước để tạo hàm bình thường hóa.

Bước 1) Chúng tôi tạo đề cử , đó là. Trong R, chúng ta có thể lưu trữ đề cử trong một biến như thế này:

nominator <- x-min(x)

Bước 2) Chúng tôi tính toán mẫu: . Chúng ta có thể sao chép ý tưởng của bước 1 và lưu trữ tính toán trong một biến:

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

Bước 3) Ta thực hiện phép chia giữa mẫu số và mẫu số.

normalize <- nominator/denominator

Bước 4) Để trả về giá trị cho hàm đang gọi, chúng ta cần truyền chuẩn hóa bên trong hàm return () để lấy đầu ra của hàm.

return(normalize)

Bước 5) Chúng tôi đã sẵn sàng sử dụng hàm bằng cách gói mọi thứ bên trong khung.

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

Hãy kiểm tra hàm của chúng ta với biến c1:

normalize(data_frame$c1)

Nó hoạt động hoàn hảo. Chúng tôi đã tạo ra chức năng đầu tiên của mình.

Các hàm là cách toàn diện hơn để thực hiện một tác vụ lặp đi lặp lại. Chúng ta có thể sử dụng công thức chuẩn hóa trên các cột khác nhau, như bên dưới:

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)

Mặc dù ví dụ đơn giản, chúng ta có thể suy ra sức mạnh của một công thức. Đoạn mã trên dễ đọc hơn và đặc biệt tránh sai sót khi dán mã.

Các hàm với điều kiện

Đôi khi, chúng ta cần đưa các điều kiện vào một hàm để cho phép mã trả về các đầu ra khác nhau.

Trong các tác vụ Học máy, chúng ta cần tách tập dữ liệu giữa tập hợp tàu và tập thử nghiệm. Tập hợp tàu cho phép thuật toán học từ dữ liệu. Để kiểm tra hiệu suất của mô hình của chúng tôi, chúng tôi có thể sử dụng bộ kiểm tra để trả về thước đo hiệu suất. R không có chức năng tạo hai tập dữ liệu. Chúng ta có thể viết hàm của riêng mình để làm điều đó. Hàm của chúng ta nhận hai đối số và được gọi là split_data (). Ý tưởng đằng sau rất đơn giản, chúng tôi nhân độ dài của tập dữ liệu (tức là số lượng quan sát) với 0,8. Ví dụ: nếu chúng ta muốn chia tập dữ liệu 80/20 và tập dữ liệu của chúng ta chứa 100 hàng, thì hàm của chúng ta sẽ nhân 0,8 * 100 = 80. 80 hàng sẽ được chọn để trở thành dữ liệu đào tạo của chúng ta.

Chúng tôi sẽ sử dụng tập dữ liệu chất lượng hàng không để kiểm tra chức năng do người dùng xác định. Tập dữ liệu chất lượng hàng không có 153 hàng. Chúng ta có thể thấy nó với đoạn mã dưới đây:

nrow(airquality)

Đầu ra:

## [1] 153 

Chúng tôi sẽ tiến hành như sau:

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

Hàm của chúng ta có hai đối số. Các đối số đào tạo là một tham số Boolean. Nếu nó được đặt thành TRUE, hàm của chúng tôi sẽ tạo tập dữ liệu huấn luyện, nếu không, nó sẽ tạo tập dữ liệu thử nghiệm.

Chúng ta có thể tiếp tục giống như chúng ta đã làm với hàm normalize (). Chúng tôi viết mã như thể nó chỉ là mã một lần và sau đó bọc mọi thứ với điều kiện vào phần thân để tạo hàm.

Bước 1:

Chúng ta cần tính toán độ dài của tập dữ liệu. Điều này được thực hiện với hàm nrow (). Nrow trả về tổng số hàng trong tập dữ liệu. Chúng tôi gọi là chiều dài thay đổi.

length<- nrow(airquality)length

Đầu ra:

## [1] 153

Bước 2:

Chúng tôi nhân chiều dài với 0,8. Nó sẽ trả về số hàng để chọn. Nó phải là 153 * 0,8 = 122,4

total_row <- length*0.8total_row

Đầu ra:

## [1] 122.4

Chúng tôi muốn chọn 122 hàng trong số 153 hàng trong tập dữ liệu chất lượng hàng không. Chúng tôi tạo một danh sách chứa các giá trị từ 1 đến total_row. Chúng tôi lưu trữ kết quả trong biến được gọi là split

split <- 1:total_rowsplit[1:5] 

Đầu ra:

## [1] 1 2 3 4 5

split chọn 122 hàng đầu tiên từ tập dữ liệu. Ví dụ, chúng ta có thể thấy rằng biến tách của chúng ta tập hợp giá trị 1, 2, 3, 4, 5, v.v. Các giá trị này sẽ là chỉ số khi chúng ta chọn các hàng để trả về.

Bước 3:

Chúng ta cần chọn các hàng trong tập dữ liệu chất lượng hàng không dựa trên các giá trị được lưu trữ trong biến phân tách. Điều này được thực hiện như thế này:

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

Đầu ra:

##[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

Bước 4:

Chúng ta có thể tạo tập dữ liệu thử nghiệm bằng cách sử dụng các hàng còn lại, 123: 153. Điều này được thực hiện bằng cách sử dụng - trước phân tách.

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

Đầu ra:

##[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

Bước 5:

Chúng ta có thể tạo điều kiện bên trong phần thân của hàm. Hãy nhớ rằng, chúng ta có một tham số là một Boolean được đặt thành TRUE theo mặc định để trả về tập huấn luyện. Để tạo điều kiện, chúng tôi sử dụng cú pháp if:

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

Đây là nó, chúng ta có thể viết hàm. Chúng tôi chỉ cần thay đổi airquality thành df vì chúng tôi muốn thử chức năng của mình với bất kỳ khung dữ liệu nào, không chỉ airquality:

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

Hãy thử chức năng của chúng tôi trên tập dữ liệu chất lượng hàng không. chúng ta nên có một tập hợp xe lửa với 122 hàng và một tập hợp thử nghiệm với 31 hàng.

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

Đầu ra:

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

Đầu ra:

## [1] 31 6

thú vị bài viết...