Giới thiệu
R là một ngôn ngữ lập trình bậc cao, nó được tạo ra với mục đích dành cho các công việc phân tích dữ liệu, thống kê và học máy. Tôi gọi R là “Super Excel” và nó còn hơn thế nữa. Trong phần trước tôi đã giới thiệu một số thao tác cơ bản với khung dữ liệu (data frame) (https://viblo.asia/p/thao-tac-co-ban-voi-khung-du-lieu-trong-r-phan-1-4P856rGW5Y3). Hãy cùng tìm hiểu thêm về chủ đề này trong bài viết này.
Thực hành trên dữ liệu nào?
R có rất nhiều tập dữ liệu cho chúng ta thực hành các câu lệnh, bạn có thể xem danh sách các tập dữ liệu sẵn có bằng hàm data()
. Tuy nhiên trong bài này tôi sẽ thao tác trên tập dữ liệu “titanic”, mặc dù nó cũng là một tập dữ liệu khá nổi tiếng tuy nhiên không có sẵn trong R. Có nhiều cách để thêm tập dữ liệu này, dưới đây tôi sẽ cài đặt thư viện “titanic”, rồi khai báo sử dụng thư viện này và sau đó chúng ta có thể sử dụng tập dữ liệu “titanic”:
> install.packages("titanic")> library(titanic)> head(titanic_train)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1103 Braund, Mr. Owen Harris male 2210 A/5211717.2500 S
2211 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 3810 PC 1759971.2833 C85 C
3313 Heikkinen, Miss. Laina female 2600 STON/O2. 31012827.9250 S
4411 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 351011380353.1000 C123 S
5503 Allen, Mr. William Henry male 35003734508.0500 S
6603 Moran, Mr. James male NA003308778.4583 Q
hàm head()
hiển thị sáu quan sát của khung dữ liệu được truyền vào. Tương tự hàm head()
là hàm tail()
, nó hiển thị sáu quan sát cuối cùng.
Data frame có cấu trúc giống bảng tính gồm các quan sát (observation) và các biến (variable), ở đây tôi sẽ dùng thuật ngữ “quan sát” đại diện cho một dòng và “biến” đại diện cho cột.
Thực hành
Truy vấn dữ liệu con
Nhu cầu phổ biến nhất trong thao tác dữ liệu là chọn ra những dữ liệu mà người phân tích quan tâm, có thể là các biến hoặc các quan sát thỏa mãn điều kiện nào đó. R là một ngôn ngữ mạnh mẽ và nó làm điều này một cách hết sức đơn giản.
Chọn các biến
Cú pháp chung là: dataframe
, nếu muốn lấy toàn bộ các quan sát chúng sẽ để trống phần row indices
:
> x <- titanic_train[,'Name']> head(x)[1]"Braund, Mr. Owen Harris"[2]"Cumings, Mrs. John Bradley (Florence Briggs Thayer)"[3]"Heikkinen, Miss. Laina"[4]"Futrelle, Mrs. Jacques Heath (Lily May Peel)"[5]"Allen, Mr. William Henry"[6]"Moran, Mr. James"
Các câu lệnh sau sẽ làm điều tương tự với câu lệnh trên: titanic_train['Name']
hoặc titanic_train$Name
.
Hoặc truy vấn nhiều hơn một biến:
> y <- titanic_train[, c('Name','Age')]> head(y)
Name Age
1 Braund, Mr. Owen Harris 22.000002 Cumings, Mrs. John Bradley (Florence Briggs Thayer)38.000003 Heikkinen, Miss. Laina 26.000004 Futrelle, Mrs. Jacques Heath (Lily May Peel)35.000005 Allen, Mr. William Henry 35.000006 Moran, Mr. James 29.69912
Tương tự, câu lệnh titanic_train[c('Name', 'Age')]
cũng có ý nghĩa giống câu lệnh trên.
Lọc điều kiện
Hãy xem một ví dụ:
> x <- titanic_train[titanic_train$Sex=='male'& titanic_train$Age >30,]> head(x)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
5503 Allen, Mr. William Henry male 35003734508.0500 S
7701 McCarthy, Mr. Timothy J male 54001746351.8625 E46 S
141403 Andersson, Mr. Anders Johan male 391534708231.2750 S
212102 Fynney, Mr. Joseph J male 350023986526.0000 S
222212 Beesley, Mr. Lawrence male 340024869813.0000 D56 S
313101 Uruchurtu, Don. Manuel E male 4000 PC 1760127.7208 C
Bây giờ kết hợp giữa việc lọc điều kiện và chọn ra các biến mong muốn:
> y <- titanic_train[titanic_train$Sex=='male'& titanic_train$Age >30, c('Name','Age','Fare')]> head(y)
Name Age Fare
5 Allen, Mr. William Henry 358.05007 McCarthy, Mr. Timothy J 5451.862514 Andersson, Mr. Anders Johan 3931.275021 Fynney, Mr. Joseph J 3526.000022 Beesley, Mr. Lawrence 3413.000031 Uruchurtu, Don. Manuel E 4027.7208
Thống kê cơ bản
Có bao nhiêu hành khách
Số hành khách chính là số quan sát của khung dữ liệu:
> nrow(titanic_train)[1]891
Vậy trong khung dữ liệu titanic_train có 891 quan sát tương ứng với 891 hành khách.
**Giá vé trung bình là bao nhiêu **
> mean(titanic_train$Fare)[1]32.20421
Độ tuổi trung bình
> mean(titanic_train$Age)[1]NA
Trong trường hợp này R không tính được trung bình của biến “Age”. Câu hỏi là tại sao lại như vậy ? Là do trong biến này có giá trị chưa xác định (missing value), vì vậy chúng ta sẽ không tính toán với các quan sát chứa missing value.
> mean(titanic_train$Age, na.rm=TRUE)[1]29.69912
Nhân tiện tôi đã kiểm tra có 177 quan sát xảy ra missing value với biến “Age”:
> sum(is.na(titanic_train$Age))[1]177
Missing values
Để kiểm tra missing value ta sử dụng hàm is.na()
:
> x <- c('a','b',NA,'d','e',NA)> is.na(x)[1]FALSEFALSETRUEFALSEFALSETRUE
Bạn hãy tự thử với câu lệnh is.na(titanic_train)
. Thậm chí ta có thể truyền cả một khung dữ liệu vào hàm is.na()
. R thật là “mạnh” !
Bây giờ hãy “lấp các khoảng trống”, Một số mô hình học máy không hoạt động được nếu có missing value trong khung dữ liệu, chúng ta sẽ thay các giá trị missing value trong biến “Age” bằng giá trị trung bình của chính nó:
> age.mean = mean(titanic_train$Age, na.rm=TRUE)> titanic_train$Age[is.na(titanic_train$Age)]= age.mean
Sắp xếp dữ liệu
Tôi có một câu hỏi: “Số phận của những người trả vé cao hoặc thấp cho chuyến đi đã ra sao?”. Để trả lời câu hỏi này, tôi sẽ sắp xếp dữ liệu theo biến “Fare” (giá vé)
> new.data = titanic_train[order(titanic_train$Fare),]> head(new.data)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
18018003 Leonard, Mr. Lionel male 36.0000000 LINE 0 S
26426401 Harrison, Mr. William male 40.00000001120590 B94 S
27227213 Tornquist, Mr. William Henry male 25.0000000 LINE 0 S
27827802 Parkes, Mr. Francis "Frank" male 29.69912002398530 S
30330303 Johnson, Mr. William Cahoone Jr male 19.0000000 LINE 0 S
41441402 Cunningham, Mr. Alfred Fleming male 29.69912002398530 S
Thứ tự sắp xếp mặc định là tăng dần, vì vậy ở câu lệnh trên chúng ta đã quan sát thấy sáu hành khách có giá vé thấp nhất. Còn những người trả vé cao nhất thì sao:
> new.data2 = titanic_train[order(-titanic_train$Fare),]> head(new.data2)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
25925911 Ward, Miss. Anna female 3500 PC 17755512.3292 C
68068011 Cardeza, Mr. Thomas Drake Martinez male 3601 PC 17755512.3292 B51 B53 B55 C
73873811 Lesurer, Mr. Gustave J male 3500 PC 17755512.3292 B101 C
282801 Fortune, Mr. Charles Alexander male 193219950263.0000 C23 C25 C27 S
898911 Fortune, Miss. Mabel Helen female 233219950263.0000 C23 C25 C27 S
34234211 Fortune, Miss. Alice Elizabeth female 243219950263.0000 C23 C25 C27 S
Thật đơn giản đến bất ngờ, hầu như không có sư khác nhau giữa hai đoạn code trên, sự khác biệt duy nhất là tôi đã thêm dấu “trừ” trong hàm order(-titanic_train$Fare)
.
Bạn hãy tự đưa ra nhận xét của mình: những người trả tiền cao thì sao, những người trả tiền thấp nhất thì sao?
Nguồn: viblo.asia