Bs. Trần Quý Phi.
Bài này lưu ý một số vấn đề về phép gán và cách gán tham số khi gọi hàm trong R
Ghi chú: Các lệnh được kiểm tra trên R ver 2.12.1
1) Phép gán
Trong ngôn ngữ lập trình một biến được xem như là một ô nhớ, khi khởi tạo (khai báo) một biến thì chương trình sẽ dành cho biến đó một ô nhớ.
Sau đó ta sẽ gán giá trị cụ thể cho nó bằng phép gán (assigment), về kỹ thuật chính là “đổ” giá trị đó vào ô nhớ của biến.
Trong R có thể có nhiều cách gán.
x <- 5 # gán 5 cho biến x
hoặc
5 –> x
hoặc
x = 5
Trường hợp không phải giá trị cụ thể, như
x <- y
thì phải hiểu là: lấy giá trị của biến y gán cho biến x (x thay đổi nhưng y thì không)
x <- 5
y <- 4
x <- y # lúc này x thay đổi, x = 4, và y cũng vẫn là 4
Cách gán bằng dấu bằng dễ dẫn đến nhầm lẫn, theo chúng tôi là nên tránh, vì
x = y # gán giá trị của y cho x
khác với
y = x # gán giá trị x cho y
Dùng “mũi tên” thì ta có ý niệm rõ ràng hơn ta muốn gán cái gì cho cái gì.
Ở đây tưởng cũng nhắc thêm là dấu bằng này không phải là sự so sánh (khác với trong toán học). Để so sánh hai giá trị của hai biến có bằng nhau không ta dùng phép toán = =
> x <- 4
> y<-5
> x == y
[1] FALSE
= = là một phép toán so sánh, cũng như phép cộng, trừ… nên nó có kết quả, trong trường hợp này là FALSE (hoặc TRUE trong trường hợp khác). Và R sẽ cho ra kết quả đó (so sánh với phép gán, không có “kết quả”), nếu không thực hiện được phép gán, nó sẽ cho kết quả FALSE, như trong trường hợp ghi chú dưới đây.
Ghi chú: Dấu cách trong phép gán <-
Không như các trường hợp khác nếu chúng ta có dấu cách giữa dấu < và – thì R không thực hiện phép gán, và báo phép gán không hiệu lực bằng giá trị FALSE
> x <- 4
> x < – 5 # phép gán không hiệu lực vì có dấu cách giữa < và -
[1] FALSE # báo là FALSE
> x
[1] 4 # x vẫn bằng 4, không phải là 5
2) Cung cấp tham số cho hàm
Một hàm có thể có các tham số (arguments). Trường hợp nhiều tham số thì phần lớn các ngôn ngữ đòi hỏi đưa các tham số vào đúng thứ tự. Một số cho phép dùng tên của tham số (đã được đặt trước) để gọi, được gọi là named arguments (tham số được đặt tên). R cho phép dùng thứ tự hoặc khai báo tên tham số tường minh. Điều này rất có ích vì thứ tự các tham số sẽ rất khó nhớ.
Ví dụ:
Ta biết có hàm rnorm cho ra một tập số liệu ngẫu nhiên tuân theo phân phối Normal. Tham số của nó là số lượng giá trị ngẫu nhiên muốn sinh, trung bình và độ lệch chuẩn. Và theo đúng thứ tự đó, nếu không sẽ gây lỗi hay hiểu nhầm
> rnorm(10,3,2)
[1] 2.8949946 2.3470456 -0.1089497 3.2691411 3.9396626 7.9169301
[7] 2.8926740 1.3174846 1.0765193 3.7753157
> rnorm(10,2,3)
[1] 6.83648867 -2.86785305 -3.63932891 -0.08547963 0.28109232 -1.87440336
[7] 3.63556130 -2.32339509 1.80359953 2.75811144
Lệnh rnorm(10,3,2) sinh 10 số liệu, với trung bình là 3, độ lệch chuẩn 2
Lệnh rnorm(10,2,3) sinh 10 số liệu, với trung bình là 2, độ lệch chuẩn 3
Cách gọi trên gọi là đối sánh toàn phần (totally matching).
Trước hết, nếu quên các tham số ta dùng hàm args (viết tắt của arguments)
> args(rnorm)
function (n, mean = 0, sd = 1)
Vậy ta biết được có ba tham số với tên là n, mean và sd
ta có thể gọi thẳng:
> rnorm(n = 10, mean = 2, sd= 3)
Hàm này hoàn toàn giống
> rnorm(n = 10, sd= 3, mean = 2)
thậm chí:
> rnorm(sd= 3, mean = 2,n = 10)
nghĩa là thứ tự có thể tùy ý, miễn là chúng ta ghi rõ tên tham số đã được đặt.
Trường hợp, ghi tên tham số nhưng không đủ thì R sẽ lấy vị trí thứ tự đã được định dối với các tham số không được ghi rõ tên, được gọi là partially matching (đối sánh từng phần)
ví dụ:
> rnorm(10, mean = 2, sd= 3) # hiểu 10 là của n
> rnorm(1000, 2, mean = 3) # hiểu 1000 là của n, 2 là của sd, nhưng:
> rnorm(2,1000, mean = 3) # … hiểu 2 là n và 1000 là sd
Thêm nữa khi dùng agrs thì ta biết được giá trị mặc định (default) tham số là giá trị sau dấu bằng.
> args(rnorm)
function (n, mean = 0, sd = 1)
Giá trị mặc định của mean là 0, sd là 1 (để ý n không có). Nghĩa là nếu ta không đưa chúng vào chúng sẽ mặc nhiên sử dụng giá trị đó
norm <-rnorm(1000) # lấy 1000 số liệu với mean = 0 và sd =1
norm <-rnorm(1000,sd=3) # lấy 1000 số liệu với mean = 0 và sd =3
nhưng:
norm <-rnorm(1000,3)
là lấy 1000 số liệu với mean = 3 (vị trí thứ hai) và sd = 1 (mặc định)
Mặt khác, vì n không có giá trị mặc định nên nếu thiếu n thì sẽ có lỗi
>rnorm(sd=3,mean=2)
Error in .Internal(rnorm(n, mean, sd)) : 'n' is missing
Ta đưa ra một ví dụ phức tạp hơn:
Việc kiểm soát các biến trước khi làm việc ở một phiên (session) mới với R rất quan trọng, đôi khi ta muốn xóa một số biến với hàm rm().
> args(rm)
function (..., list = character(0L), pos = -1, envir = as.environment(pos),
inherits = FALSE)
phần chấm chấm cũng là arguments: số tham số đưa được vào là có thể thay đổi ví dụ
>rm(x,y,z) # xóa các biến x,y,z; list, pos, envir, inherit lấy các giá trị mặc định.
trường hợp có dấu chấm chấm thì không thể định số thứ tự theo kiểu đối sánh từng phần, điều này dễ hiểu vì dấu chấm chấm hàm ý là R sẽ không biết trước được số lượng tham số được đưa vào.
Đồng thời chấm chấm cũng có giá trị mặc định là … không có gì cả (không đưa vào tham số, vì vậy
> rm() # chấm chấm không có, các giá trị còn lại là giá trị mặc định
không có lỗi, và cũng … không có tác dụng gì cả.
Mặt khác, để ý tham số list = character nên muốn dùng list ta phải ghi
> rm(“x”) # tương đương với rm(x)
nhưng ghi
> rm(“x”,”y”)
là sai, vì R sẽ hiểu, “x” là dành cho … và “y” là dành cho list.
phải là
> rm (x,”y”) # khá kỳ cục, nhưng để hiểu !!!
hoặc là
> rm(c(“x”,”y”))
lúc này c(“x”,”y”) được cho là gán với list, và … bỏ trống.
Cuối cùng để xóa tất cả biến (trong workspace .Data) ta sẽ dùng hàm ls() để nhận được danh sách các biến
> rm(list= ls())
lại nói thêm (nếu mọi người còn kiên nhẫn) tại sao không ghi
>rm(ls(())
xem như ls() giống c(“x”,”y”)? Không được, ta sẽ mắc lỗi:
> rm(ls())
Error in rm(ls()) : ... must contain names or character strings
ls() là hàm, không phải là tên hoặc chuỗi (string) như hàm rm yêu cầu.
Ghi chú: mặc dù c cũng là hàm, nhưng là hàm primitive, giá trị được trả về trực tiếp trước khi R lượng giá hàm rm(), còn ls() không phải vậy (là hàm internal). Chỗ này không sure lắm
No comments:
Post a Comment