Các hàm trong lập trình R với ví dụ
⚡ Tóm tắt thông minh
Các hàm trong gói R là một tập hợp các lệnh được đặt dưới một tên duy nhất, do đó một tác vụ lặp lại có thể được thực thi chỉ bằng một lệnh gọi duy nhất. Nó cung cấp các công cụ hỗ trợ toán học và thống kê tích hợp sẵn, các hàm do người dùng định nghĩa, và phạm vi môi trường.pingVà các lập luận có điều kiện cũng được trình bày ở đây với các ví dụ minh họa.

Hàm trong R là gì?
A chức năng, trong môi trường lập trình, là một tập hợp các hướng dẫn. Một lập trình viên xây dựng một hàm để tránh lặp lại cùng một nhiệm vụ, hoặc giảm phức tạp.
Một chức năng nên được
- được viết ra để thực hiện một nhiệm vụ cụ thể
- có thể hoặc không bao gồm các đối số
- chứa một cơ thể
- Có thể trả về một hoặc nhiều giá trị, hoặc cũng có thể không.
Cách tiếp cận chung đối với hàm là sử dụng phần đối số làm đầu vào, nuôi thân hình một phần và cuối cùng trả lại một đầu ra. Cú pháp của một hàm như sau:
function (arglist) { #Function body }
R các chức năng tích hợp quan trọng
Có rất nhiều hàm dựng sẵn 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 phần thân hàm. Đố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ẽ lấy 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 tên của chính hàm đó trong bảng điều khiển.
Typing Tên hàm không có dấu ngoặc sẽ in ra mã nguồn của nó, như hình ảnh bên dưới trong bảng điều khiển.
Chúng ta sẽ thấy ba nhóm chức năng hoạt động
- Chức năng chung
- hàm toán học
- Hàm 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ư cbind(), rbind(), range(), sắp xếp ()và order(). Mỗi hàm này có một nhiệm vụ cụ thể, nhận các tham số và trả về kết quả. Sau đây là những hàm quan trọng mà bạn cần biết:
hàm khác biệt ()
Nếu bạn làm việc trên chuỗi thời gian, bạn cần phải dừng chuỗi bằng cách lấy giá trị độ trễ. Một quá trình đứng yên Cho phép giá trị trung bình, phương sai và tự tương quan không đổi theo thời gian. Điều này chủ yếu giúp cải thiện khả năng dự đoán chuỗi thời gian. Điều này có thể được thực hiện bằng 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()` để làm cho chuỗi trở nên ổn định. Hàm `diff()` chấp nhận một đối số, một vectơ, và trả về sự khác biệt trễ và lặp lại phù hợp.
Lưu ýChúng ta thường cần tạo dữ liệu ngẫu nhiên, nhưng để phục vụ mục đích học tập và so sánh, chúng ta muốn các số được tạo ra phải giống hệt nhau trên tất cả các máy. Để đảm bảo tất cả đề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ố định điểm bắt đầu của bộ tạo số giả ngẫu nhiên, do đó mọi máy đều tạo ra cùng một chuỗi. Nếu không có set.seed(), mỗi lần chạy sẽ trả về một chuỗi khác nhau.
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')
Hai biểu đồ bên dưới đặt chuỗi dữ liệu tích lũy ban đầu bên cạnh chuỗi dữ liệu đã được lấy hiệu số, lúc này biến động xung quanh một giá trị trung bình không đổi.
hàm chiều dài()
Trong nhiều trường hợp, chúng ta cần biết độ dài của một vectơ để tính toán hoặc sử dụng trong vòng lặp for. Hàm length() đếm số hàng trong vectơ x. Đoạn mã sau nhập tập dữ liệu cars và trả về số hàng.
Lưu ý: length() trả về số phần tử trong một vectơ. Nếu hàm này được truyền vào một ma trận Hoặc đối với một data frame, số lượng cột sẽ được trả về.
dt <- cars
## number columns
length(dt)
Đầu ra:
## [1] 1
## number rows
length(dt[,1])
Đầu ra:
## [1] 50
Các hàm toán học
Ngoài các hàm hỗ trợ chung, R còn có một loạt các hàm toán học hoạt động trên từng phần tử của một vectơ.
| Operator | Mô tả Chi tiế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 1 x_vector <- seq(45,55, by = 1) #logarithm log(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
#exponential
exp(x_vector)
#squared root
sqrt(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
#factorial
factorial(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ê
Trong khi các hàm toán học biến đổi giá trị, các hàm thống kê lại tóm tắt chúng. Phiên bản cài đặt tiêu chuẩn của R chứa rất nhiều hàm thống kê. Trong hướng dẫn này, chúng ta sẽ xem xét ngắn gọn những hàm quan trọng nhất.
Các hàm thống kê cơ bản
| Operator | Mô tả Chi tiết |
|---|---|
| nghĩa là (x) | Giá trị 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 |
| tỷ lệ (x) | Điểm chuẩn (z-score) của x |
| lượng tử(x) | Tứ phân vị của x |
| tóm tắt(x) | Tóm tắt về x: trung bình, tối thiểu, tối đa, v.v. |
speed <- dt$speed
speed
# Mean speed of cars dataset
mean(speed)
Đầu ra:
## [1] 15.4
# Median speed of cars dataset
median(speed)
Đầu ra:
## [1] 15
# Variance speed of cars dataset
var(speed)
Đầu ra:
## [1] 27.95918
# Standard deviation speed of cars dataset
sd(speed)
Đầu ra:
## [1] 5.287644
# Standardize vector speed of cars dataset
head(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 dataset
quantile(speed)
Đầu ra:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset
summary(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 dựng sẵn của R.
Lưu ýHãy cẩn thận với lớp của lập luận, tức là kiểu dữ liệu số, Boolean hoặc chuỗi. Ví dụ, nếu cần truyền một giá trị chuỗi, 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 tự viết hàm riêng vì phải hoàn thành một nhiệm vụ cụ thể mà không có hàm nào có sẵn. Hàm do người dùng định nghĩa bao gồm... tên, đối số và thân hình.
function.name <- function(arguments) { computations on the arguments some other code }
Lưu ý: Một cách tốt là đặt tên cho hàm do người dùng xác định khác với hàm có sẵn. Nó tránh nhầm lẫn.
Một hàm đối số
Trong đoạn mã tiếp theo, chúng ta 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 4 square_function(4)
Code Giải thích
- Hàm này được đặt tên là Square_function; 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ể truyền số nguyên, vectơ hoặc ma trận
- Hàm lấy đầ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 :Error: object 'square_function' not Found cho biết hàm này không tồn tại.
Môi trường Scoping
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 sẽ mở một môi trường mỗi khi RStudio được khởi động.
Môi trường cấp cao nhất hiện có là môi trường toàn cầu, được gọi là R_GlobalEnv. Và chúng ta có môi trường địa phương.
Chúng ta 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ể thấy tất cả các biến và hàm được tạo trong R_GlobalEnv.
Danh sách trên sẽ khác nhau tùy thuộc vào mã lịch sử mà bạn thực thi trong RStudio.
Lưu ý rằng nĐối số của hàm square_function không nằm trong môi trường toàn cục này.
Một môi trường mới được tạo ra cho mỗi hàm. Trong ví dụ trên, hàm square_function() tạo ra một môi trường mới bên trong... môi trường toàn cầu.
Để làm rõ sự khác biệt giữa toàn cầu và địa phương về môi trường, chúng ta hãy nghiên cứu ví dụ sau.
Hàm này lấy 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ả đầu ra 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ị 10 trong tất cả các lệnh gọi hàm và có thể truy cập được bất cứ 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 bỏ `y` trước khi chạy mã này bằng rm r
Kết quả cũng là 15 khi chúng ta gọi f(5) nhưng trả về lỗi khi chúng ta cố in giá trị y. Biến y không có trong môi trường toàn cầu.
Cuối cùng, R sử dụng định nghĩa biến mới nhất để truyền vào bên trong thân 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 biến ay bên trong thân hàm một cách rõ ràng.
Hàm đa đối số
Chúng ta có thể viết một hàm có nhiều hơn một đối số. Hãy xem xét hàm được gọi là “thời gian”. Đây 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?
Các nhà khoa học dữ liệu cần thực hiện nhiều tác vụ lặp đi lặp lại. Hầu hết thời gian, chúng ta sao chép và dán các đoạn mã một cách lặp đi lặp lại. Ví dụ, việc chuẩn hóa một biến là rất cần thiết trước khi chúng ta chạy một thuật toán nào đó. học máy thuật toán. 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. Tibble cho đến nay 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 frame data_frame <- tibble( c1 = rnorm(50, 5, 1.5), c2 = rnorm(50, 5, 1.5), c3 = rnorm(50, 5, 1.5), )
Chúng ta sẽ tiến hành tính toán hàm số đã mô tả ở trên theo hai bước. Bước đầu tiên, chúng ta sẽ tạo một biến có tên là c1_norm, là hệ số điều chỉnh của c1. Bước thứ hai, chúng ta chỉ cần sao chép và dán mã của c1_norm và thay thế bằng c2 và c3.
Chi tiết 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 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)
Đầu ra:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
Nó hoạt động. Chúng ta 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ệ một cách hoàn hảo các biến c1, c2 và c3.
Tuy nhiên, phương pháp này dễ mắc lỗi. Chúng ta có thể sao chép và quên thay đổi tên cột sau khi dán. Do đó, cách làm tốt hơn là viết một hàm mỗi khi 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 đoạn mã thành một công thức và gọi nó bất cứ khi nào cần thiết. Để viết hàm riêng, chúng ta cần cung cấp:
- Tên: chuẩn 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 đơn giản là công thức mà chúng tôi muốn trả về.
Chúng ta sẽ tiến hành từng bước để tạo hàm chuẩn hóa.
Bước 1) Chúng ta tạo ra tử số, đó là x – min(x). Trong R, chúng ta có thể lưu trữ tử số trong một biến như sau:
nominator <- x-min(x)
Bước 2) Chúng ta tính mẫu số: max(x) – min(x). Chúng ta có thể lặp lại ý tưởng của bước 1 và lưu kết quả tính toán vào một biến:
denominator <- max(x)-min(x)
Bước 3) Chúng tôi thực hiện phép chia giữa đề cử và mẫu số.
normalize <- nominator/denominator
Bước 4) Để trả về giá trị cho hàm gọi, chúng ta cần chuyển normalize bên trong return() để lấy đầu ra của hàm.
return(normalize)
Bước 5) Chúng ta đã sẵn sàng sử dụng hàm này bằng cách bao bọc nó lại.ping Mọi thứ nằm bên trong dấu ngoặc.
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) }
Hãy kiểm tra hàm của chúng tôi 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.
Hàm là một 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 vẫn có thể suy ra sức mạnh của công thức. Đoạn mã trên dễ đọc hơn và tránh được những lỗi thường gặp khi sao chép mã.
Hàm có điều kiện
Hàm normalize() luôn thực hiện cùng một việc. Đôi khi, chúng ta cần đưa các điều kiện vào hàm để cho phép mã trả về các kết quả khác nhau.
Trong các tác vụ của Machine Learning, chúng ta cần phân chia tập dữ liệu thành tập huấn luyện và tập kiểm tra. Tập huấn luyện 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, chúng ta 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 riêng của mình để làm điều đó. Hàm của chúng ta có 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 theo tỷ lệ 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 huấn luyện của chúng ta.
Chúng tôi sẽ sử dụng tập dữ liệu chất lượng không khí để kiểm tra chức năng do người dùng xác định. Bộ dữ liệu chất lượng không khí 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 ta 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 tôi có hai đối số. Đối số train là tham số Boolean. Nếu được đặt thành TRUE, hàm của chúng tôi sẽ tạo tập dữ liệu train, nếu không, nó sẽ tạo tập dữ liệu thử nghiệm.
Chúng ta có thể tiến hành như đã làm với hàm normalize(). Chúng ta viết mã như thể đó chỉ là mã chạy một lần và sau đó gói tất cả các điều kiện vào phần thân hàm để tạo thành hàm.
Bước 1:
Chúng ta cần tính toán độ dài của tập dữ liệu. Việc này được thực hiện bằng hàm nrow(). Nrow trả về tổng số hàng trong tập dữ liệu. Chúng tôi gọi độ 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.8 total_row
Đầu ra:
## [1] 122.4
Chúng tôi muốn chọn 122 hàng trong số 153 hàng trong bộ dữ liệu chất lượng không khí. 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à chia
split <- 1:total_row split[1:5]
Đầu ra:
## [1] 1 2 3 4 5
tách 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 phân chia của chúng ta tập hợp các giá trị 1, 2, 3, 4, 5, v.v. Các giá trị này sẽ là chỉ mục 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 không khí 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 chia.
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 thân hàm. Hãy nhớ rằng, chúng ta có một chuỗi đối số có giá trị Boolean được đặt thành TRUE theo mặc định để trả về tập hợp tàu. Để tạo điều kiện, chúng ta sử dụng cú pháp if:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Thế là xong, chúng ta có thể viết hàm. Chúng tôi chỉ cần thay đổi chất lượng không khí 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, không chỉ chất lượng không khí:
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) } }
Hãy thử nghiệm hàm của chúng ta trên tập dữ liệu chất lượng không khí. Chúng ta sẽ có một tập huấn luyện với 122 hàng và một tập kiểm tra 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






