“Tôi nghe tôi quên. Tôi nhìn tôi nhớ. Tôi làm tôi hiểu.”
Trong R, giá trị logic có thể là TRUE (viết tắt là T) hoặc FALSE (viết tắt là F). Chúng có thể được hiểu là có/không, một/không, hài lòng/không hài lòng, v.v. Thông thường, chúng báo hiệu liệu một điều kiện đã được thỏa mãn hay một tham số nên được bật hoặc tắt. Việc gán các giá trị logic thành một đối tượng cũng tương tự như việc gán các giá trị số.
a <- TRUE
a
## [1] TRUE
b <- F
b
## [1] FALSE
d <- c(T, F, F, F, T, F, T, T, T, F, T, F)
d
## [1] TRUE FALSE FALSE FALSE TRUE FALSE TRUE TRUE TRUE FALSE TRUE FALSE
length(d)
## [1] 12
(q <- matrix(data = d, nrow = 3, ncol = 4, byrow = a))
## [,1] [,2] [,3] [,4]
## [1,] TRUE FALSE FALSE FALSE
## [2,] TRUE FALSE TRUE TRUE
## [3,] TRUE FALSE TRUE FALSE
| Toán tử | Ý nghĩa |
|---|---|
==
|
Bằng |
!=
|
Khác |
>
|
Lớn hơn |
<
|
Nhỏ hơn |
>=
|
Lớn hơn hoặc bằng |
<=
|
Nhỏ hơn hoặc bằng |
1 == 2
## [1] FALSE
1 > 2
## [1] FALSE
(2-1) <= 2
## [1] TRUE
1 != (2 + 3)
## [1] TRUE
f <- c(3, 2, 1, 4, 1, 2, 1, -1, 0, 3)
g <- c(4, 1, 2, 1, 1, 0, 0, 3, 0, 4)
length(f) = length(g)
f == g
## [1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
f < g
## [1] TRUE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE TRUE
f <= g
## [1] TRUE FALSE TRUE FALSE TRUE FALSE FALSE TRUE TRUE TRUE
f <= (g+10)
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
f < 3
## [1] FALSE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
q <- f == g
q
## [1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
Để biết có ít nhất một phần tử của vectơ logic nào đó có giá trị TRUE
ta dùng hàm any().
any(q)
## [1] TRUE
Để biết có phải tất cả các phẩn tử của vectơ logic nào đó đều là TRUE
ta dùng hàm all().
all(q)
## [1] FALSE
qq <- f<=(g+10)
qq
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
any(qq)
## [1] TRUE
all(qq)
## [1] TRUE
Bài tập 4.1
c(6, 9, 7, 3, 6, 7, 9, 6, 3, 6, 6, 7, 1, 9, 1). Hãy xác
định:
| Toán tử | Ý nghĩa | Kết quả |
|---|---|---|
&
|
Và (so sánh từng phần tử của vectơ) |
TRUE & TRUE là TRUE TRUE & FALSE là FALSE FALSE & TRUE là FALSE FALSE & FALSE là FALSE |
&&
|
Và (so sánh đơn lẻ) |
Tương tự như &
|
|
|
Hoặc (so sánh từng phần tử của vectơ) |
TRUE | TRUE là TRUE TRUE | FALSE là TRUE FALSE | TRUE là TRUE FALSE | FALSE là FALSE |
||
|
Hoặc (so sánh đơn lẻ) |
Tương tự như |
|
!
|
Phủ định |
!TRUE là FALSE !FALSE là TRUE |
FALSE||((T&&TRUE)||FALSE)
## [1] TRUE
!TRUE&&TRUE
## [1] FALSE
(T&&(TRUE||F))&&FALSE
## [1] FALSE
(6<4)||(3!=1)
## [1] TRUE
f <- c(T,F,F,F,T,F,T,T)
g <- c(F,T,F,T,F,F,F,F)
f&g
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
f|g
## [1] TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE
f&&g
## Warning in f && g: 'length(x) = 8 > 1' in coercion to 'logical(1)'
## Warning in f && g: 'length(x) = 8 > 1' in coercion to 'logical(1)'
## [1] FALSE
f||g
## Warning in f || g: 'length(x) = 8 > 1' in coercion to 'logical(1)'
## [1] TRUE
Bài tập 4.2
c(7, 1, 7, 10, 5, 9, 10, 3, 10, 8)
là vector_1. Xác định các phần tử lớn hơn 5 HOẶC bằng
2.c(8, 8, 4, 4, 5, 1, 5, 6, 6, 8) là
vector_2. Xác định các phần tử nhỏ hơn hoặc bằng 6 VÀ khác 4.vector_1 và thỏa
(b) trong vector_2.vector_tong là tổng từng phần tử của
vector_1 và vector_2. Hãy xác định:
vector_tong lớn hơn hoặc bằng 14 nhưng
khác 15.vector_tong và vector_1 có giá trị lớn hơn 4
hoặc nhỏ hơn hay bằng 2.Trong R, TRUE được xem là 1 và FALSE được xem là 0.
TRUE+TRUE
## [1] 2
FALSE-TRUE
## [1] -1
T+T+F+T+F+F+T
## [1] 4
Trong một số trường hợp khi dùng giá trị logic (TRUE, FALSE), chúng ta có thể dùng giá trị số của chúng để thay thế.
1&&1
## [1] TRUE
1||0
## [1] TRUE
0&&1
## [1] FALSE
Các giá trị logic có thể được dùng để trích xuất các phần tử của các đối tượng trong R như vectơ, ma trận, mảng, v.v.
myvec <- c(5,-2.3,4,4,4,6,8,10,40221,-8)
Như trước đây, để trích xuất các phần tử mang giá trị âm của
myvec chúng ta dùng chỉ số chỉ vị trí.
myvec[c(2, 10)]
## [1] -2.3 -8.0
Chúng ta cũng có thể dùng giá trị logic để trích xuất các phần tử
mang giá trị âm của myvec. Khi đó giá trị tương ứng với
TRUE sẽ được trích ra.
myvec[c(F,T,F,F,F,F,F,F,F,T)]
## [1] -2.3 -8.0
Thực chất vectơ logic c(F,T,F,F,F,F,F,F,F,T) tương đương
với myvec < 0.
myvec < 0
## [1] FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Do đó ta có thể trích các phần tử có giá trị âm của
myvec với cú pháp đơn giản và dễ hiểu như sau:
myvec[myvec < 0] # Trích phần tử của myvec thỏa đk myvec < 0
## [1] -2.3 -8.0
Chúng ta có thể trích phần tử của myvec thỏa
myvec > 0 và myvec < 1000.
myvec[(myvec > 0) & (myvec < 1000)]
## [1] 5 4 4 4 6 8 10
Chúng ta có thể thay thế các phần tử mang giá trị âm.
myvec[myvec < 0] <- -200
myvec
## [1] 5 -200 4 4 4 6 8 10 40221 -200
Hàm which() cũng rất hữu ít trong việc trích xuất dựa
trên giá trị logic. Nó cho chúng ta biết vị trí mang giá trị TRUE.
which(c(T, F, F, T, T))
## [1] 1 4 5
which(myvec < 0)
## [1] 2 10
myvec[-which(myvec < 0)] # trích các phần tử không âm
## [1] 5 4 4 4 6 8 10 40221
myvec[myvec >= 0]
## [1] 5 4 4 4 6 8 10 40221
Việc trích xuất phần tử của ma trận và mảng dựa trên các giá trị logic cũng được thực hiện tương tự.
A <- matrix(c(0.3,4.5,55.3,91,0.1,105.5,-4.2,8.2,27.9), nrow=3, ncol=3)
A
## [,1] [,2] [,3]
## [1,] 0.3 91.0 -4.2
## [2,] 4.5 0.1 8.2
## [3,] 55.3 105.5 27.9
A[c(T,F,F),c(F,T,T)]
## [1] 91.0 -4.2
A < 1
## [,1] [,2] [,3]
## [1,] TRUE FALSE TRUE
## [2,] FALSE TRUE FALSE
## [3,] FALSE FALSE FALSE
A[A < 1]
## [1] 0.3 0.1 -4.2
A > 25
## [,1] [,2] [,3]
## [1,] FALSE TRUE FALSE
## [2,] FALSE FALSE FALSE
## [3,] TRUE TRUE TRUE
which(A > 25)
## [1] 3 4 6 9
which(A > 25, arr.ind = T)
## row col
## [1,] 3 1
## [2,] 1 2
## [3,] 3 2
## [4,] 3 3
Bài tập 4.3
myvec <- c(7,5,6,1,2,10,8,3,8,2) và
thực hiện các yêu cầu sau:
myvec1.myvec sau khi đã
loại bỏ các phần tử lớn hơn hay bằng 5.myvec1 ở câu (a)(i) để tạo ma trận \(2\times 3\) bằng cách điền các phần tử theo
dòng và đặt tên là mat. Sau đó hãy thực hiện các yêu cầu
sau:
mat bởi bình phương của
phần tử ở dòng 1 cột 2 của chính mat.mat bây giờ đều
nhỏ hơn hoặc bằng 25 và lớn hơn 4.c(10,5,1,4,7,4,3,3,1,3,4,3,1,7,8,3,7,3) để tạo
mảng \(3\times 2\times 3\) và đặt tên
là arr. Sau đó hãy thực hiện các yêu cầu sau:
arr nhỏ hơn 3 hoặc lớn hơn
hay bằng 7 bởi giá trị 100.myvec ở câu (a). Sử dụng vectơ
c(F, T) để trích mỗi thành phần thứ 2 của
myvec. Nếu thay thế c(F, T) bởi c(0, 1) thì R có cho cùng
kết quả không?Chuỗi ký tự là một kiểu dữ liệu phổ biến khác trong R và được dùng để biểu diễn văn bản. Để tạo một chuỗi, chỉ cần nhập văn bản giữa hai dấu ngoặc kép.
chac <- "This is a character string!"
chac
## [1] "This is a character string!"
length(chac)
## [1] 1
nchar(chac)
## [1] 27
b <- "23.3"
b
## [1] "23.3"
b*2
## Error in b * 2: non-numeric argument to binary operator
"alpha" == "alpha"
## [1] TRUE
"alpha" != "beta"
## [1] TRUE
"alpha" <= "beta"
## [1] TRUE
"gamma" > "Alpha"
## [1] TRUE
"Alpha" > "alpha"
## [1] TRUE
Tương tự như tạo vectơ số, chúng ta dùng hàm c() để tạo
vectơ chuỗi ký tự.
q <- c("awesome", "R", "is")
q
## [1] "awesome" "R" "is"
length(q)
## [1] 3
c("alpha", "beta", "gamma") == "beta"
## [1] FALSE TRUE FALSE
Để ghép các chuỗi ký tự lại với nhau chúng ta dùng hàm
cat() hoặc hàm paste(). Sự khác nhau giữa hai
hàm này nằm ở chỗ hàm cat() không tạo ra đối tượng mà xuất
trực tiếp kết quả ra cửa sổ consol, còn hàm paste() tạo ra
một đối tượng trong R có thể lưu trữ được.
cat(q[2], q[3], "totally", q[1], "!")
## R is totally awesome !
paste(q[2], q[3], "totally", q[1], "!")
## [1] "R is totally awesome !"
paste(q[2], q[3], "totally", q[1],"!", sep="---")
## [1] "R---is---totally---awesome---!"
paste(q[2], q[3], "totally", q[1], "!", sep="")
## [1] "Ristotallyawesome!"
a <- 3
b <- 4.4
cat("The value stored as 'a' is ", a, ".", sep="")
## The value stored as 'a' is 3.
paste("The value stored as 'b' is ", b, ".", sep="")
## [1] "The value stored as 'b' is 4.4."
cat("The result of a+b is ", a, "+", b, "=", a+b, ".", sep="")
## The result of a+b is 3+4.4=7.4.
paste("Is ", a+b," less than 10? That’s totally ", a+b<10, ".", sep="")
## [1] "Is 7.4 less than 10? That’s totally TRUE."
Khi làm việc với chuỗi ký tự, chúng ta thường cần đến những trình tự
thoát sau đây.
| Trình tự thoát (escape sequence) | Ý nghĩa |
|---|---|
\n
|
Xuống dòng |
\t
|
Tab ngang |
\b
|
Phím lùi |
\
|
Dấu gạch chéo ngược |
\"
|
Dấu ngoặc kép |
cat("Here is a string\nsplit\tto new\n\n\tlines")
## Here is a string
## split to new
##
## lines
cat("I really want a backslash: \\\nand a double quote: \"")
## I really want a backslash: \
## and a double quote: "
Chúng ta có thể trích và thay thế một phần của chuỗi bằng cách dùng
hàm substr().
f <- "This is a character string!"
substr(f, start = 21, stop = 27)
## [1] "string!"
substr(f, start = 1, stop = 4) <- "Here"
f
## [1] "Here is a character string!"
Việc thay thế chuỗi sẽ dễ dàng hơn nếu chúng ta dùng hàm
sub() và gsub().
chac <- "How much wood could a woodchuck chuck"
sub(pattern = "chuck", replacement = "hurl", x = chac)
## [1] "How much wood could a woodhurl chuck"
gsub(pattern = "chuck", replacement = "hurl", x = chac)
## [1] "How much wood could a woodhurl hurl"
Bài tập 4.4
The quick brown fox
jumped over
the lazy dogs
num1 <- 4 và
num2 <- 0.75. Hãy viết một dòng code R có sử dụng 2
vectơ trên để xuất ra kết quả sau:[1] "The result of multiplying 4 by 0.75 is 3"
"How much wood could a woodchuck chuck.
"if a woodchuck could chuck wood".wood bằng metal trong
chuỗi (i)."Two 6-packs for $12.99". Từ chuỗi vừa tạo
hãy:
6-packs.$10.99.| Tên | Giới tính | Tháng sinh |
|---|---|---|
| Lan | Nữ | Tháng 4 |
| Hoa | Nữ | Tháng 1 |
| Huệ | Nữ | Tháng 1 |
| Tài | Nam | Tháng 9 |
| Tâm | Nữ | Tháng 11 |
| Tín | Nam | Tháng 7 |
| Thanh | Nam | Tháng 7 |
| Hương | Nữ | Tháng 6 |
Nhập tên ở dạng vectơ chuỗi ký tự.
ten <- c("Lan", "Hoa", "Hue", "Tai", "Tam", "Tin", "Thanh", "Huong")
Để tạo vectơ factor chúng ta dùng hàm factor().
gioitinh.chuoi <- c("Nu", "Nu", "Nu", "Nam", "Nu", "Nam", "Nam", "Nu")
gioitinh.chuoi.fac <- factor(gioitinh.chuoi)
gioitinh.chuoi.fac
## [1] Nu Nu Nu Nam Nu Nam Nam Nu
## Levels: Nam Nu
Chúng ta cũng có thể mã hóa nữ thành 0 và nam thành 1.
gioitinh.so <- c(0, 0, 0, 1, 0, 1, 1, 0)
gioitinh.so.fac <- factor(gioitinh.so)
gioitinh.so.fac
## [1] 0 0 0 1 0 1 1 0
## Levels: 0 1
Factor hoàn toàn tương tự như vectơ nhưng có phần thông tin thêm gọi
là levels. Nó cho biết các giá trị có thể có của factor. Để xác
định levels của factor chúng ta dùng hàm
levels().
levels(gioitinh.so.fac)
## [1] "0" "1"
levels(gioitinh.chuoi.fac)
## [1] "Nam" "Nu"
Chúng ta có thể thay thế level bằng các số khác.
levels(gioitinh.so.fac) <- c("1", "2")
gioitinh.so.fac
## [1] 1 1 1 2 1 2 2 1
## Levels: 1 2
Trích xuất các phần tử của factor cũng tương tự như vectơ.
gioitinh.chuoi.fac[2:5]
## [1] Nu Nu Nam Nu
## Levels: Nam Nu
gioitinh.chuoi.fac[c(1:3, 5, 8)]
## [1] Nu Nu Nu Nu Nu
## Levels: Nam Nu
ten[gioitinh.chuoi.fac == 'Nam']
## [1] "Tai" "Tin" "Thanh"
Giới tính là biến định tính định danh chỉ có 2 mức độ là nam và nữ nên việc đưa về factor khá dễ dàng. Trong khi đó tháng sinh là biến định tính có thứ bậc nên việc đưa về factor yêu cầu phải có thứ bậc. Nếu chúng ta đưa biến tháng sinh thành factor một cách tương tự như biến giới tính thì chuyện gì sẽ xảy ra?
thang.sinh <- c("Thang 4", "Thang 1", "Thang 1", "Thang 9", "Thang 11", "Thang 7", "Thang 7", "Thang 6")
thang.sinh.fac <- factor(thang.sinh)
thang.sinh.fac
## [1] Thang 4 Thang 1 Thang 1 Thang 9 Thang 11 Thang 7 Thang 7 Thang 6
## Levels: Thang 1 Thang 11 Thang 4 Thang 6 Thang 7 Thang 9
Đầu tiên chúng ta thấy levels của tháng sinh chỉ có 6 mức độ trong khi tháng sinh có tất cả 12 giá trị có thể có. Tiếp theo là gì? Không so sánh được thứ bậc của tháng sinh.
thang.sinh.fac[2] < thang.sinh.fac[1]
## Warning in Ops.factor(thang.sinh.fac[2], thang.sinh.fac[1]): '<' not meaningful
## for factors
## [1] NA
Do đó chúng ta cần đưa tháng sinh về factor bằng cách khai báo đầy đủ levels và thứ bậc của nó.
thang = c("Thang 1", "Thang 2", "Thang 3", "Thang 4", "Thang 5", "Thang 6", "Thang 7", "Thang 8", "Thang 9", "Thang 10", "Thang 11", "Thang 12" )
thang.sinh.fac = factor(thang.sinh, levels = thang, ordered = T)
thang.sinh.fac
## [1] Thang 4 Thang 1 Thang 1 Thang 9 Thang 11 Thang 7 Thang 7 Thang 6
## 12 Levels: Thang 1 < Thang 2 < Thang 3 < Thang 4 < Thang 5 < ... < Thang 12
Lúc này ta thấy tháng sinh có 12 mức độ và có thứ bậc.
thang.sinh.fac[2] < thang.sinh.fac[1]
## [1] TRUE
Để đưa một biến định lượng liên tục về dạng định tính có thứ bậc ta
có thể dùng hàm cut(). Giả sử ta có một biến định lượng
liên tục.
Y <- c(0.53, 5.4, 1.5, 3.33, 0.45, 0.01, 2, 4.2, 1.99)
Ta đưa Y về dạng định tính có thứ bậc như sau: Từ [0; 2) là nhỏ, [2; 4) là vừa, [4; 6] là lớn.
br <- c(0, 2, 4, 6)
cut(Y,breaks=br,right=F,include.lowest=T)
## [1] [0,2) [4,6] [0,2) [2,4) [0,2) [0,2) [2,4) [4,6] [0,2)
## Levels: [0,2) [2,4) [4,6]
lab <- c("Nho","Vua","Lon")
cut(Y,breaks=br,right=F,include.lowest=T,labels=lab, ordered_result = T)
## [1] Nho Lon Nho Vua Nho Nho Vua Lon Nho
## Levels: Nho < Vua < Lon
Bài tập 4.5. Khảo sát 20 sinh viên của một trường đại học được số liệu như sau:
| Hàm/Toán tử | Ý nghĩa |
|---|---|
TRUE (T), FALSE (F)
|
Giá trị logic |
==, !=, >, <,
>=, <=
|
Toán tử quan hệ |
any()
|
Có bất kỳ phần tử của vectơ logic là TRUE không |
all()
|
Có phải tất cả phần tử của vectơ logic đều là TRUE |
&, &&, |,
||, !
|
Toán tử logic |
which()
|
Xác định chỉ số vị trí của các phần tử mang giá trị TRUE |
" "
|
Tạo chuỗi ký tự |
nchar()
|
Đếm số ký tự của chuỗi |
cat()
|
Nối chuỗi ký tự (không tạo ra đối tượng) |
paste()
|
Nối chuỗi ký tự (tạo đối tượng) |
\
|
Thoát khỏi chuỗi |
substr()
|
Trích chuỗi |
sub(), gsub()
|
Tìm và thay thế chuỗi |
factor()
|
Tạo factor |
levels()
|
Xác định mức độ của factor |
cut()
|
Tạo factor từ biến liên tục |