Cách tạo biến trong R
Biến (variable) trong R là một cái tên gắn với một giá trị. Bạn tạo biến bằng mũi tên gán <-: tên đứng trước mũi tên, giá trị đứng sau.
Ba biến, ba loại giá trị khác nhau, và không có khai báo kiểu nào cả: R suy ra kiểu từ chính giá trị (xem thêm ở bài kiểu dữ liệu). Khi biến đã tồn tại, bạn dùng nó ở bất cứ đâu bạn dùng được giá trị:
Gán lại cũng làm y như vậy. Một biến sẵn sàng nhận giá trị mới, kể cả kiểu mới, ngay khi bạn gán lần nữa:
R không hề phàn nàn khi một chuỗi biến thành một số. Sự linh hoạt đó tiện lợi, nhưng nếu ý nghĩa của một biến thay đổi giữa chừng script, đó thường là dấu hiệu bạn nên chọn một tên mới.
Vì sao R dùng <- thay cho =
Đây là câu hỏi ai cũng đặt ra: age = 30 cũng chạy được, vậy sao mọi cuốn sách, hướng dẫn phong cách và package R đều dùng mũi tên?
Vì = trong R là hai thứ khác nhau tùy nơi nó xuất hiện. Ở cấp cao nhất, nó gán. Bên trong lời gọi hàm, nó khớp một đối số theo tên, và không tạo biến:
Nếu bạn thử mean(values, na.rm <- TRUE), bạn sẽ vô tình tạo một biến toàn cục tên na.rm và truyền TRUE theo vị trí: hợp lệ, sai, và khó phát hiện. Quy ước giữ cho code dễ đọc rất đơn giản:
<-luôn có nghĩa là phép gán.=luôn có nghĩa là "đối số này nhận giá trị này" bên trong lời gọi một hàm.
Theo đúng sự phân chia đó, mọi dòng R bạn đọc đều cho biết ngay thứ gì đang được tạo ra và thứ gì đang được truyền vào. Đây là quy tắc phong cách phổ biến nhất trong thế giới R: RStudio thậm chí dành riêng một phím tắt cho <- (Alt+-).
Những người anh em ít dùng: ->, = và assign()
R còn hai cách gán khác, đáng để nhận ra dù bạn hiếm khi viết chúng.
Mũi tên ngược -> gán theo chiều ngược lại: giá trị trước, tên sau:
Thỉnh thoảng bạn sẽ thấy nó ở cuối một pipeline dài ("tính hết chỗ này, rồi lưu lại"), nhưng hầu hết hướng dẫn phong cách khuyên tránh dùng: người đọc nhìn vào đầu dòng để tìm tên đang được định nghĩa.
assign() tạo biến từ một chuỗi, nghĩa là tên biến có thể được tạo ra lúc chạy:
Trông thì khéo, nhưng gần như lúc nào cũng là công cụ sai: một loạt biến đánh số thực ra là một vector hoặc một list đang đội lốt. Chỉ dùng assign() khi tên thật sự phải được tính toán; hàm đi kèm get("score") đọc một biến theo tên dạng chuỗi.
Quy tắc đặt tên
R chấp nhận những tên:
- Chứa chữ cái, chữ số, dấu chấm (
.) và dấu gạch dưới (_). - Bắt đầu bằng chữ cái, hoặc bằng dấu chấm không theo sau bởi chữ số.
- Không phải từ khóa dành riêng (
if,for,TRUE,NULL,functionvà vài từ khác).
Vì vậy những tên này đều hợp lệ:
Còn những tên này thì không:
2nd_user: không được bắt đầu bằng chữ số._temp: cũng không được bắt đầu bằng dấu gạch dưới (khác với Python).user-name: dấu gạch ngang là phép trừ, không phải ký tự của tên.TRUE: từ khóa dành riêng.
Tên phân biệt chữ hoa chữ thường: total, Total và TOTAL là ba biến không liên quan, và R sẽ không cảnh báo khi bạn gõ nhầm mà vô tình tạo ra một biến mới.
Liệt kê và xóa: ls() và rm()
Mọi biến bạn tạo đều nằm trong workspace (môi trường toàn cục). ls() liệt kê những gì đang có, và rm() xóa chúng:
Hai chi tiết đáng biết. Thứ nhất, rm(list = ls()) xóa sạch cả workspace: tiện ở đầu một phiên khám phá, nhưng phá hoại ở mọi chỗ khác. Thứ hai, những tên bắt đầu bằng dấu chấm (như .cache) bị ẩn khỏi ls() trừ khi bạn gọi ls(all.names = TRUE), giống quy ước tệp ẩn trên Unix.
Quy ước đặt tên: dùng snake_case
Ngoài các quy tắc bắt buộc, cộng đồng R hiện đại (và hướng dẫn phong cách tidyverse) đã thống nhất một số quy ước:
lower_snake_casecho biến và hàm:retry_count,fit_model.- Dấu chấm trong tên hợp lệ nhưng đã lỗi thời: base R đầy những tên thời
data.framenhưmy.data, nhưng dấu chấm còn mang ý nghĩa trong hệ thống phương thức S3 của R (print.data.framelà "phương thức print dành cho data frame"), nên code mới tránh dùng. - Không tiền tố kiểu Hungary, không camelCase: bạn sẽ thấy
camelCasetrong các package cũ, nhưng snake_case là nơi cả hệ sinh thái đã chọn. - R không có hằng số thật sự; quy ước là đặt tên các giá trị muốn làm hằng số bằng chữ in hoa (
MAX_RETRIES <- 5) và đơn giản là không gán lại chúng.
Hãy chọn tên mang tính mô tả và nhất quán. avg_score tốn thêm bốn lần gõ phím so với as nhưng giúp mọi người đọc sau này khỏi phải lục lại đầu script.
Điều cần nhớ
name <- valuetạo một biến; cộng đồng dành=cho đối số của hàm.->vàassign()có tồn tại; bạn sẽ đọc thấy chúng thường hơn mức bạn nên viết chúng.- Tên gồm chữ cái, chữ số, dấu chấm và dấu gạch dưới; không được bắt đầu bằng chữ số hay dấu gạch dưới, và phân biệt chữ hoa chữ thường.
ls()cho xem workspace,rm()dọn dẹp nó.- Viết
snake_casevà code của bạn sẽ trông giống R mà mọi người khác đang viết hôm nay.
Tiếp theo: những loại giá trị mà các biến đó thực sự chứa, gồm numeric, integer, character và logical.
Câu hỏi thường gặp
Làm sao để tạo biến trong R?
Viết tên, mũi tên gán <- rồi đến giá trị: age <- 30. R tự suy ra kiểu từ giá trị, không có bước khai báo. age = 30 cũng chạy được ở cấp cao nhất, nhưng quy ước của cộng đồng là <-.
<- và = trong R khác nhau thế nào?
Ở cấp cao nhất của script, chúng làm cùng một việc. Bên trong lời gọi hàm thì không: mean(x, na.rm = TRUE) dùng = để khớp một đối số theo tên, không tạo biến. Vì = đóng hai vai tùy ngữ cảnh, các hướng dẫn phong cách R dành <- cho phép gán và = cho đối số.
Làm sao để xóa biến trong R?
rm(x) xóa biến x khỏi workspace. rm(list = ls()) xóa tất cả, tiện để bắt đầu lại từ đầu nhưng nguy hiểm khi đang phân tích dở. ls() liệt kê những gì đang tồn tại.
Tên biến trong R có được chứa dấu chấm không?
Có: my.data là một tên hoàn toàn hợp lệ, và code R cũ dùng dấu chấm ở khắp nơi. Phong cách hiện đại ưu tiên dấu gạch dưới (my_data) vì dấu chấm còn mang ý nghĩa trong hệ thống phương thức S3 của R, khiến tên có dấu chấm dễ bị đọc nhầm.