├── requirements.r ├── img ├── author_image.png └── shield_image.png ├── datasets ├── planets.RData ├── shining_list.RData ├── all_wars_matrix.RData ├── chapter6.R ├── chapter5.R └── chapter3.R ├── README.md ├── .gitattributes ├── .gitignore ├── course.yml ├── chapter6.Rmd ├── chapter1.Rmd ├── chapter4.Rmd ├── chapter5.Rmd ├── chapter3.Rmd └── chapter2.Rmd /requirements.r: -------------------------------------------------------------------------------- 1 | # no additional requirements 2 | -------------------------------------------------------------------------------- /img/author_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-vietnamese/master/img/author_image.png -------------------------------------------------------------------------------- /img/shield_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-vietnamese/master/img/shield_image.png -------------------------------------------------------------------------------- /datasets/planets.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-vietnamese/master/datasets/planets.RData -------------------------------------------------------------------------------- /datasets/shining_list.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-vietnamese/master/datasets/shining_list.RData -------------------------------------------------------------------------------- /datasets/all_wars_matrix.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-vietnamese/master/datasets/all_wars_matrix.RData -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction to R in Vietnamese 2 | 3 | Anh Hoang Duc has translated the original introduction in R course (GitHub) into Vietnamese. This repository contains all the source files, in Vietnamese, that correspond to the course that is live on DataCamp. -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /datasets/chapter6.R: -------------------------------------------------------------------------------- 1 | actors <- c("Jack Nicholson","Shelley Duvall","Danny Lloyd","Scatman Crothers","Barry Nelson") 2 | sources <- c("IMDb1","IMDb2","IMDb3") 3 | comments <- c("Best Horror Film I Have Ever Seen","A truly brilliant and scary film from Stanley Kubrick","A masterpiece of psychological horror") 4 | scores <- c(4.5,4,5) 5 | reviews <- data.frame(scores,sources,comments) 6 | shining_list <- list(moviename="The Shining",actors=actors, reviews=reviews) 7 | 8 | save(shining_list, file = "datasets/shining_list.RData") -------------------------------------------------------------------------------- /datasets/chapter5.R: -------------------------------------------------------------------------------- 1 | name <- c("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"); 2 | type <- c("Terrestrial planet", "Terrestrial planet", "Terrestrial planet", "Terrestrial planet", "Gas giant", "Gas giant", "Gas giant", "Gas giant") 3 | diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883); 4 | rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67); 5 | rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE); 6 | planets_df <- data.frame(name, type, diameter, rotation, rings) 7 | 8 | save(planets_df, file = "datasets/planets.RData") -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /datasets/chapter3.R: -------------------------------------------------------------------------------- 1 | # Tạo ma trận 2 | box_office_all <- c(461, 314.4, 290.5, 247.9, 309.3, 165.8) 3 | movie_names <- c("A New Hope","The Empire Strikes Back","Return of the Jedi") 4 | col_titles <- c("US","non-US") 5 | star_wars_matrix <- matrix(box_office_all, nrow = 3, byrow = TRUE, dimnames = list(movie_names, col_titles)) 6 | 7 | # Tạo ma trận 2 8 | box_office_all2 <- c(474.5, 552.5, 310.7, 338.7, 380.3, 468.5) 9 | movie_names2 <- c("The Phantom Menace", "Attack of the Clones", "Revenge of the Sith") 10 | star_wars_matrix2 <- matrix(box_office_all2, nrow = 3, byrow = TRUE, dimnames = list(movie_names2, col_titles)) 11 | 12 | # Nối hai ma trận thành một 13 | all_wars_matrix <- rbind(star_wars_matrix, star_wars_matrix2) 14 | 15 | # Xóa tất cả ngoại trừ all_wars_matrix 16 | rm(box_office_all) 17 | rm(movie_names) 18 | rm(col_titles) 19 | rm(star_wars_matrix) 20 | rm(box_office_all2) 21 | rm(movie_names2) 22 | rm(star_wars_matrix2) 23 | 24 | save(all_wars_matrix, file = "datasets/all_wars_matrix.RData") 25 | -------------------------------------------------------------------------------- /course.yml: -------------------------------------------------------------------------------- 1 | title: Hướng dẫn cơ bản về R 2 | author_field: Anh Hoang Duc 3 | author_bio: "Anh is a data vizualizer & applied modeller, 4 | co-founder of RAnalytics.vn. 5 | He provides training in R & data analytics in Hanoi, Vietnam. 6 | His courses provide various aspects of R such as data analysis, data wrangling, data vizualization or predictive model. 7 | Anh holds master degree in Quantitative Methods in Economics." 8 | description: "Trong loạt bài giảng này, bạn sẽ học được cách làm chủ những kiến thức cơ bản 9 | của ngôn ngữ lập trình thông kê R, bao gồm factors, list và data frame. Những kiến thức này 10 | sẽ giúp bạn bắt đầu công việc của một nhà phân tích dữ liệu. Với hơn 2 triệu người sử dụng R 11 | trên toàn thế giới, R đang nhanh chóng trở thành ngôn ngữ lập trình số một trong 12 | giới thống kê và khoa học số liệu. Hàng năm, số lượng người dùng R tăng hơn 40% và ngày 13 | càng có nhiều cơ quan và tổ chức sử dụng R trong hoạt động phân tích thường nhật. Hãy bắt đầu 14 | khám phá sức mạnh và học cách sử dụng R ngay từ ngày hôm nay." 15 | from: "r-base-prod:27" 16 | -------------------------------------------------------------------------------- /chapter6.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : Chương 6 3 | title : Lists 4 | description : Lists, không giống như véc-tơ, có thể lưu trữ các kiểu dữ liệu khác nhau. Trong chương này, chúng ta sẽ học cách khởi tạo, đặt tên và lọc các thành phần trong list. 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:2afcdb6a76ec91bf266de9b2ac295d844d7bb004 7 | ## Tại sao chúng ta lại cần sử dụng list? 8 | 9 | Xin chúc mừng bạn! Đến thời điểm này, bạn đã làm quen với các kiểu dữ liệu sau: 10 | 11 | - **Véc-tơ** (mảng một chiều): có thể lưu trữ dữ liệu kiểu số, ký tự hoặc logic. Các giá trị trong véc-tơ phải có cùng định dạng. 12 | - **Ma trận** (mảng hai chiều): có thể lưu trữ dữ liệu kiểu số, ký tự hoặc logic. Các giá trị trong ma trận phải có cùng định dạng 13 | - **Data frame** (đối tượng hai chiều): có thể lưu trữ dữ liệu kiểu số, ký tự hoặc logic. Trong cùng một cột, các giá trị phải có cùng định dạng. Tuy nhiên, các cột khác nhau có thể chứa dữ liệu kiểu khác nhau. 14 | 15 | Cũng khá là dễ hiểu cho những bạn mới học R phải không? ;-) 16 | 17 | *** =instructions 18 | Click 'Submit Answer' để bắt đầu tìm hiểu kiến thức về list! 19 | 20 | *** =hint 21 | Ấn nút 'Submit Answer'. 22 | 23 | *** =pre_exercise_code 24 | ```{r} 25 | # no pec 26 | ``` 27 | 28 | *** =sample_code 29 | ```{r} 30 | # Ấn nút 'Submit Answer' 31 | ``` 32 | 33 | *** =solution 34 | ```{r} 35 | # Ấn nút 'Submit Answer' 36 | ``` 37 | 38 | *** =sct 39 | ```{r} 40 | success_msg("Sẵn sàng! Xử lý bài tập tiếp theo nào.") 41 | ``` 42 | 43 | 44 | --- type:NormalExercise xp:100 skills:1 key:68f93c5c504616bd18876da52cd123277d56fc8b 45 | ## Tại sao chúng ta lại cần sử dụng list? (2) 46 | 47 | Trong R, **list** cũng tương tự như danh sách check-list những việc bạn cần phải làm vậy. Mỗi đối tượng trong list có thể có độ dài, định dạng khác nhau về những thứ bạn cần phải thực hiện. 48 | 49 | List cho phép ta tập hợp nhiều đối tượng khác nhau theo thứ tự cho trước trở thành một đối tượng. Những đối tượng này có thể là ma-trận, véc-tơ, data frame hay thậm chí là một list khác. Các đối tượng không nhất thiết phải có mối liên hệ với nhau. 50 | 51 | 52 | Ta có thể nói rằng, list là một kiểu định dạng dữ liệu "siêu đẳng" mà bạn có thể lưu trữ bất cứ thông tin nào. 53 | 54 | *** =instructions 55 | Click 'Submit Answer' để bắt đầu bài tập đầu tiên về list. 56 | 57 | *** =hint 58 | Click 'Submit Answer' để bắt đầu bài tập đầu tiên về list. 59 | 60 | *** =pre_exercise_code 61 | ```{r} 62 | # no pec 63 | ``` 64 | 65 | *** =sample_code 66 | ```{r} 67 | # Click 'Submit Answer' để bắt đầu bài tập đầu tiên về list. 68 | ``` 69 | 70 | *** =solution 71 | ```{r} 72 | # Click 'Submit Answer' để bắt đầu bài tập đầu tiên về list. 73 | ``` 74 | 75 | *** =sct 76 | ```{r} 77 | success_msg("Tốt lắm. Bắt đầu thực hành nhé!") 78 | ``` 79 | 80 | 81 | --- type:NormalExercise xp:100 skills:1 key:4beee9cb532c889903218b49b83ab5ef133eac83 82 | ## Tạo một list 83 | 84 | Ta hãy tạo một list đầu tiên! Để xây dựng một list, bạn có thể sử dụng hàm [`list()`](http://www.rdocumentation.org/packages/base/functions/list): 85 | 86 | ``` 87 | my_list <- list(comp1, comp2 ...) 88 | ``` 89 | 90 | Tham số trong hàm list là các đối tượng sẽ được lưu trữ trong list. Nhớ rằng các đối tượng đó có thể là ma-trận, véc-tơ, hay một list khác... 91 | 92 | *** =instructions 93 | Tạo một list tên là `my_list`, list này chứa các đối tượng `my_vector`, `my_matrix` và `my_df`. 94 | 95 | *** =hint 96 | Sử dụng hàm [`list()`](http://www.rdocumentation.org/packages/base/functions/list) với các đối tượng trong list là `my_vector`, `my_matrix` và `my_df`, nhớ ngăn cách các đối tượng bằng dấu phẩy . 97 | 98 | *** =pre_exercise_code 99 | ```{r} 100 | # no pec 101 | ``` 102 | 103 | *** =sample_code 104 | ```{r} 105 | # Véc-tơ số từ 1 đến 10 106 | my_vector <- 1:10 107 | 108 | # Ma-trận số từ 1 đến 9 109 | my_matrix <- matrix(1:9, ncol = 3) 110 | 111 | # 10 giá trị đầu tiên của tập dữ liệu mtcars 112 | my_df <- mtcars[1:10,] 113 | 114 | # Tạo list với các đối tượng đã tạo: 115 | my_list <- 116 | ``` 117 | 118 | *** =solution 119 | ```{r} 120 | # Véc-tơ số từ 1 đến 10 121 | my_vector <- 1:10 122 | 123 | # Ma-trận số từ 1 đến 9 124 | my_matrix <- matrix(1:9, ncol = 3) 125 | 126 | # 10 giá trị đầu tiên của tập dữ liệu mtcars 127 | my_df <- mtcars[1:10,] 128 | 129 | # Tạo list với các đối tượng đã tạo 130 | my_list <- list(my_vector, my_matrix, my_df) 131 | ``` 132 | 133 | *** =sct 134 | ```{r} 135 | msg = "Không thay đổi các giá trị của `my_vector`, `my_matrix` or `my_df`!" 136 | test_object("my_vector", undefined_msg = msg, incorrect_msg = msg) 137 | test_object("my_matrix", undefined_msg = msg, incorrect_msg = msg) 138 | test_object("my_df", undefined_msg = msg, incorrect_msg = msg) 139 | test_object("my_list", 140 | incorrect_msg = "Có vẻ như `my_list` không chứa chính xác các đối tượng. Hãy chắc chắn rằng bạn đã sử dụng các biến `my_vector`, `my_matrix` và `my_df` trong hàm `list()` và ngăn cách chúng bởi dấu phẩy.") 141 | success_msg("Tuyệt vời! Làm bài tập tiếp theo nhé.") 142 | ``` 143 | 144 | 145 | --- type:NormalExercise xp:100 skills:1 key:89dd0126568b1ff5a84033c571907a8a282245e4 146 | ## Tạo tên cho các đối tượng trong list 147 | 148 | Giống như khi bạn tạo các danh sách check-list, để tránh việc có thể quên tên các đối tượng của list, bạn có thể đặt tên cho chúng. 149 | 150 | ``` 151 | my_list <- list(name1 = your_comp1, 152 | name2 = your_comp2) 153 | ``` 154 | 155 | Phương pháp này sẽ tạo một list với các đối tượng tên là `name1`, `name2`, v.v... Sau khi đã tạo list, nếu bạn muốn đặt tên các đối tượng, bạn có thể sử dụng hàm `names()` như đối với véc-tơ. Các câu lệnh dưới đây là tương đương với câu lệnh ở phía trên. 156 | 157 | ``` 158 | my_list <- list(your_comp1, your_comp2) 159 | names(my_list) <- c("name1", "name2") 160 | ``` 161 | 162 | *** =instructions 163 | - Thay đổi các câu lệnh ở bài tập trước bằng cách thêm tên các đối tượng chứa trong list. Đặt tên `my_vector` thành `vec`, `my_matrix` thành `mat` và `my_df` thành `df`. 164 | - Hiển thị `my_list` để bạn có thể xem kết quả. 165 | 166 | *** =hint 167 | 168 | Phương pháp đầu tiên, phương pháp gán tên cho các đối tượng trong list, là phương pháp đơn giản nhất. Phương pháp đó được thực hiện như sau: 169 | 170 | ``` 171 | my_list <- list(vec = my_vector) 172 | ``` 173 | 174 | *** =pre_exercise_code 175 | ```{r} 176 | # no pec 177 | ``` 178 | 179 | *** =sample_code 180 | ```{r} 181 | # Véc-tơ số từ 1 đến 10 182 | my_vector <- 1:10 183 | 184 | # Ma-trận số từ 1 đến 9 185 | my_matrix <- matrix(1:9, ncol = 3) 186 | 187 | # 10 giá trị đầu tiên của tập dữ liệu mtcars 188 | my_df <- mtcars[1:10,] 189 | 190 | # Tạo list với các đối tượng đã tạo 191 | my_list <- list(my_vector, my_matrix, my_df) 192 | 193 | # Hiển thị kết quả 194 | 195 | ``` 196 | 197 | *** =solution 198 | ```{r} 199 | # Véc-tơ số từ 1 đến 10 200 | my_vector <- 1:10 201 | 202 | # Ma-trận số từ 1 đến 9 203 | my_matrix <- matrix(1:9, ncol = 3) 204 | 205 | # 10 giá trị đầu tiên của tập dữ liệu mtcars 206 | my_df <- mtcars[1:10,] 207 | 208 | # Tạo list với các đối tượng đã tạo 209 | my_list <- list(vec = my_vector, mat = my_matrix, df = my_df) 210 | 211 | # Hiển thị kết quả 212 | my_list 213 | ``` 214 | 215 | *** =sct 216 | ```{r} 217 | msg = "Không thay đổi các giá trị củ `my_vector`, `my_matrix` và `my_df`!" 218 | test_object("my_vector", undefined_msg = msg, incorrect_msg = msg) 219 | test_object("my_matrix", undefined_msg = msg, incorrect_msg = msg) 220 | test_object("my_df", undefined_msg = msg, incorrect_msg = msg) 221 | test_object("my_list", 222 | incorrect_msg = "Có vẻ như `my_list` không chứa chính xác các đối tượng. ") 223 | test_object("my_list", eq_condition = "equal", 224 | incorrect_msg = "Có vẻ như `my_list` không chứa chính xác các đối tượng. Hãy chắc chắn rằng bạn đã sử dụng các biến `my_vector`, `my_matrix` và `my_df` trong hàm `list()` . Chắc chắn rằng bạn sử dụng tên `vec`, `mat` và `df` theo thứ tự."); 225 | test_output_contains("my_list", incorrect_msg = "Đừng quên hiển thị `my_list` trên màn hình tương tác! Đơn giản là thêm `my_list` ở trên editor.") 226 | success_msg("Tuyệt vời! Bạn không chỉ biết cách tạo list, bạn còn biết cách đặt tên cho chúng nữa rồi! Trăm hay không bằng tay quen. Xem tiếp bài tập tiếp theo nhé!") 227 | ``` 228 | 229 | 230 | --- type:NormalExercise xp:100 skills:1 key:19fd17cc792ef870c1558b3a9bae08c1d1e3acae 231 | ## Tạo tên cho các đối tượng trong list (2) 232 | 233 | Là một con nghiền xem phim, bạn quyết định bắt đầu lưu trữ thông tin về các bộ phim hấp dẫn bằng list. 234 | 235 | Bắt đầu bằng việc tạo list cho bộ phim "The Shining". Chúng ta tạo các biến `mov`, `act` và `rev` trên R. 236 | 237 | *** =instructions 238 | 239 | Hoàn thành các câu lệnh ở bên để tạo `shining_list`, một list chứa 3 đối tượng sau: 240 | 241 | - moviename: định dạng chuỗi ký tự chứa thông tin về tên bộ phim (lưu trong biến `mov`) 242 | - actors: véc-tơ chứa thông tin về diễn viên chính (lưu trữ trong `act`) 243 | - reviews: data frame chứa các thông tin về lượt đánh giá của khán giả (lưu trữ trong `rev`) 244 | 245 | Đừng quên đặt tên các đối tượng trong list lần lượt là moviename, actors và reviews. 246 | 247 | *** =hint 248 | `shining_list <- list(moviename = mov)` chỉ là một phần đáp án mà thôi; bạn còn phải thêm `act` và `rev` vào trong list với tên phù hợp. 249 | 250 | *** =pre_exercise_code 251 | ```{r} 252 | mov <- "The Shining" 253 | act <- c("Jack Nicholson","Shelley Duvall","Danny Lloyd","Scatman Crothers","Barry Nelson") 254 | sources <- c("IMDb1","IMDb2","IMDb3") 255 | comments <- c("Best Horror Film I Have Ever Seen","A truly brilliant and scary film from Stanley Kubrick","A masterpiece of psychological horror") 256 | scores <- c(4.5,4,5) 257 | rev <- data.frame(scores, sources, comments) 258 | rm(scores, sources, comments) 259 | ``` 260 | 261 | *** =sample_code 262 | ```{r} 263 | # Các biến mov, act và rev 264 | 265 | # Hoàn thành câu lệnh sau để tạo shining_list 266 | shining_list <- list(moviename = mov) 267 | ``` 268 | 269 | *** =solution 270 | ```{r} 271 | # Các biến mov, act và rev 272 | 273 | # Hoàn thành câu lệnh sau để tạo shining_list 274 | shining_list <- list(moviename = mov, actors = act, reviews = rev) 275 | ``` 276 | 277 | *** =sct 278 | ```{r} 279 | msg = "Không thay đổi các giá trị các biến đã khởi tạo!" 280 | lapply(c("mov", "rev", "act"), test_object, undefined_msg = msg, incorrect_msg = msg) 281 | test_object("shining_list",eq_condition = "equal", 282 | incorrect_msg = "Có vẻ như `shining_list` không chứa các đối tượng chính xác. Các đối tượng lần lượt là `mov`, `act`, và `rev`.") 283 | success_msg("Tuyệt vời! Giờ bạn đã biết cách khởi tạo và đặt tên list. Tương tự như chương trước, chúng ta hãy học cách lấy các giá trị từ list.") 284 | ``` 285 | 286 | 287 | --- type:NormalExercise xp:100 skills:1 key:1ef3278944562caef64b9927dd2ddb6ee52334cd 288 | ## Lựa chọn các giá trị từ list 289 | 290 | Trong list của bạn thường chứa các giá trị dạng số. Do đó, để lấy một hoặc nhiều giá trị từ list cũng chẳng phải là việc hoàn toàn dễ dàng. 291 | 292 | Một phương pháp để lấy một giá trị là sử dụng thứ tự của đối tượng đó. Ví dụ, để lấy giá trị đầu tiên của `shining_list`, bạn có thể sử dụng: 293 | 294 | ``` 295 | shining_list[[1]] 296 | ``` 297 | Một phương pháp nhanh chóng để kiểm tra là gõ câu lệnh trên màn hình tương tác. Lưu ý: để lựa chọn các giá trị từ véc-tơ, bạn có thể sử dụng dấu ngoặc vuông `[ ]`. Đừng nhầm lẫn chúng với nhau. 298 | 299 | Bạn cũng có thể sử dụng tên của các đối tượng với dấu `[[ ]]` hoặc `$`. Cả hai phương pháp sẽ lấy ra data frame chưa các thông tin đánh giá của khán giả. 300 | 301 | ``` 302 | shining_list[["reviews"]] 303 | shining_list$reviews 304 | ``` 305 | 306 | Bên cạnh việc lấy các giá trị của list, bạn thường xuyên cần phải lấy một giá trị cụ thể từ các đối tượng đó. Ví dụ, với câu lệnh `shining_list[[2]][1]`, kết quả sẽ trả cho bạn đối tượng thứ 2 trong list, `actors` (`shining_list[[2]]`), và giá trị đầu tiên trong đối tượng đó (`[1]`). Khi gõ câu lệnh trên vào màn hình tương tác, bạn sẽ thấy kết quả hiển thị là Jack Nicholson. 307 | 308 | *** =instructions 309 | - Lựa chọn đối tượng chứa thông tin về diễn viên (actor) từ list `shining_list` 310 | - Lựa chọn giá trị thứ hai từ đối tượng vừa chọn 311 | 312 | *** =hint 313 | - Để lọc ra các thông tin actors, bạn có thể sử dụng `$actors`. 314 | - Để lựa chọn giá trị thứ 3, ta sử dụng câu lệnh `shining_list$actors[3]`. Ta cần phải thay đổi điều gì để lựa chọn giá trị thứ 2? 315 | 316 | *** =pre_exercise_code 317 | ```{r} 318 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/shining_list.RData")) 319 | ``` 320 | 321 | *** =sample_code 322 | ```{r} 323 | # shining_list đang được load từ hệ thống 324 | 325 | # Hiển thị véc-tơ actors 326 | 327 | 328 | # Hiển thị giá trị thứ 2 của véc-tơ actors 329 | 330 | ``` 331 | 332 | *** =solution 333 | ```{r} 334 | # shining_list đang được load từ hệ thống 335 | 336 | # Hiển thị véc-tơ actors 337 | shining_list$actors 338 | 339 | # Hiển thị giá trị thứ 2 của véc-tơ actors 340 | shining_list$actors[2] 341 | ``` 342 | 343 | *** =sct 344 | ```{r} 345 | msg <- "Không thay đối giá trị list `shining_list!" 346 | test_object("shining_list", undefined_msg = msg, incorrect_msg = msg) 347 | test_output_contains("shining_list$actors", incorrect_msg = "Bạn có lựa chọn chính xác véc-tơ chứa actors? Bạn có thể sử dụng câu lệnh `shining_list$actors`") 348 | test_output_contains("shining_list$actors[2]", incorrect_msg = "Để lựa chọn diễn viên thứ 2 từ véc-tơ actors, bạn có thể thực hiện như sau: `shining_list$actors` cho phép hiển thị véc-tơ actors, sau đó bạn có thể thêm `[2]` để lựa chọn giá trị thứ 2.") 349 | success_msg("Tuyệt vời! Lựa chọn giá trị từ list cũng dễ thôi đúng không? Làm bài tập tiếp theo nhé!") 350 | ``` 351 | 352 | 353 | --- type:NormalExercise xp:100 skills:1 key:ca3f7b71504ff93940cf65889d406a58c5b0019c 354 | ## Thêm các thông tin vào trong list 355 | 356 | Khá là tự hào với list đầu tiên của mình, bạn có cho các thành viên của câu lac bộ xem phim cùng xem. Tuy nhiên, một thành viên nhiều kinh nghiệm có tên M.McDowell nhận xét rằng, bạn quên thông tin về năm trình chiếu. Và rằng bạn muốn trở thành chủ tịch câu lạc bộ trong năm sau, bạn quyết định thêm các thông tin này vào trong list của mình. 357 | 358 | Để thêm các đối tượng trong list, bạn có thể sử dụng hàm [`c()`](http://www.rdocumentation.org/packages/base/functions/c) tương tự như khi thực hiện với véc-tơ 359 | 360 | ``` 361 | ext_list <- c(my_list , my_val) 362 | ``` 363 | 364 | Câu lệnh này đơn giản là thêm đối tượng `my_val` vào list ban đầu `my_list`. Đối tượng mới được thêm vào sẽ đứng ở cuối list 365 | 366 | Nếu bạn muốn đặt tên cho đối tượng mới được thêm vào, bạn có thể đơn giản sử dụng câu lệnh như ở bài tập phần trước. 367 | 368 | ``` 369 | ext_list <- c(my_list, my_name = my_val) 370 | ``` 371 | 372 | *** =instructions 373 | - Hoàn thiện câu lệnh dưới đây sao cho đối tượng `year` được thêm vào `shining_list`, `year` mang giá trị 1980. Gán kết quả vào `shining_list_full`. 374 | - Cuối cùng, xem cấu trúc của list `shining_list_full` với hàm [`str()`](http://www.rdocumentation.org/packages/utils/functions/str). 375 | 376 | *** =hint 377 | 378 | Xem câu lệnh ví dụ dưới đây, câu lệnh này có thể giúp bạn lúc ban đầu: 379 | 380 | ``` 381 | shining_list <- c(shining_list, ...) 382 | ``` 383 | Bạn vẫn còn phải thêm một vài lệnh sau dâu ba chấm. 384 | 385 | *** =pre_exercise_code 386 | ```{r, eval = FALSE} 387 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/shining_list.RData")) 388 | ``` 389 | 390 | *** =sample_code 391 | 392 | ```{r} 393 | # shining_list đang được load 394 | 395 | # Chúng ta quên điều gì đó; thêm biên year vào trongshining_list 396 | shining_list_full <- 397 | 398 | # Hiển thị shining_list_full 399 | 400 | ``` 401 | 402 | *** =solution 403 | 404 | ```{r} 405 | # shining_list đang được load 406 | 407 | # Sử dụng c() để thêm year vào list shining_list 408 | shining_list_full <- c(shining_list, year = 1980) 409 | 410 | # Hiển thị shining_list_full 411 | str(shining_list_full) 412 | ``` 413 | 414 | *** =sct 415 | ```{r} 416 | msg = "Không thay đổi các giá trị `shining_list!" 417 | test_object("shining_list", undefined_msg = msg, incorrect_msg = msg) 418 | test_object("shining_list_full", eq_condition = "equal", 419 | incorrect_msg = paste("Bạn đã thêm biến `year` vào trong `shining_list` một cách chính xác chưa,", 420 | "giá trị của year là 1980? Bạn có thể sử dụng `c(shining_list, year = 1980)`")) 421 | test_function("str", "object", incorrect_msg = "Đừng quên hiển thị cấu trúc list `shining_list_full` với câu lệnh `str()`.") 422 | success_msg("Tuyệt vời! Đây là bài tập cuối cùng về list. Giờ bạn đã có một kiến thức cơ bản vững chắc về lập trình ngôn ngữ với R. Tuy nhiên còn rất nhiều kiến thức thú vị khác mà bạn có thể tìm hiểu. Hãy tham gia thử các khóa học của Data Camp và chúc bạn sớm thành công trên con đường trở thành một chuyên gia phân tích dữ liệu!") 423 | ``` 424 | 425 | 426 | -------------------------------------------------------------------------------- /chapter1.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : Chương 1 3 | title : Giới thiệu căn bản về R 4 | description : "Trong chương này, chúng ta sẽ bắt đầu tìm hiểu về R. Bạn sẽ được học cách sử dụng màn hình tương tác (console) để tính toán và gán biến. Thêm vào đó, bạn sẽ làm quen với các loại dữ liệu cơ bản trong R. Ta cùng bắt đầu nào!" 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:15d729634a 7 | ## Phương pháp học trên DataCamp 8 | 9 | Để giải các bài tập, bạn gõ các câu lệnh R vào trình soạn thảo (editor) phía tay phải . Sau khi bạn nhấp chuột vào nút "Submit Answer", R sẽ xử lý từng dòng lệnh, sau đó thông báo cho bạn biết kết quả mình làm đúng hay làm sai. Kết quả của câu lệnh của bạn sẽ được hiển thị tại bảng điều khiển ở góc dưới bên phải. 10 | 11 | Ký tự `#` được dùng để thêm chú thích trong R, nhờ vậy mà khi xem xét các câu lệnh, người đọc có thể nắm được cách thức bạn phân tích và xử lý dữ liệu. R sẽ bỏ qua và không xử lý các đoạn chú thích này, do đó, kết quả của câu lệnh sẽ không bị thay đổi. Ví dụ, _Tính 3 + 4_ trong editor ở phải được coi là một chú thích. 12 | 13 | Lưu ý: Bạn cũng có thể thực hiện các câu lệnh R ngay trong console để kiểm tra kết quả câu lệnh. 14 | 15 | *** =instructions 16 | - Trong trình soạn thảo bên phải đã có sẵn câu lệnh mẫu. Bạn có phân biệt được dòng nào là câu lệnh R và dòng nào là các chú thích không? 17 | - Thêm một câu lệnh để tính tổng của 6 và 12, rồi nhấp chuột vào nút "Submit Answer". 18 | 19 | *** =hint 20 | Hãy thêm câu lệnh để tính tổng của 6 và 12, giống như ví dụ đã cho trong các câu lệnh mẫu. 21 | 22 | *** =pre_exercise_code 23 | ```{r} 24 | # no pec 25 | ``` 26 | 27 | *** =sample_code 28 | ```{r} 29 | # Tính 3 + 4 30 | 3 + 4 31 | 32 | # Tính 6 + 12 33 | 34 | ``` 35 | 36 | *** =solution 37 | ```{r} 38 | # Tính 3 + 4 39 | 3 + 4 40 | 41 | # Tính 6 + 12 42 | 6 + 12 43 | ``` 44 | 45 | *** =sct 46 | ```{r} 47 | test_output_contains("18", incorrect_msg = "Bạn cần thêm `6 + 12` trên một dòng lệnh mới. Đừng bắt đầu dòng lệnh với `#`, câu lệnh của bạn sẽ không được R xử lý đâu!") 48 | success_msg("Tuyệt vời! Bạn đã thấy kết quả của câu lệnh trên console chưa? Giờ thì bạn đã làm quen với trình duyệt, ta cùng học thêm về R nhé!") 49 | ``` 50 | 51 | --- type:NormalExercise xp:100 skills:1 key:720745eda5 52 | ## Dùng R để tính toán 53 | 54 | Ở mức độ cơ bản nhất, bạn có thể dùng R như một máy tính đơn giản. Hãy xem những phép tính dưới đây: 55 | 56 | - Cộng: `+` 57 | - Trừ: `-` 58 | - Nhân: `*` 59 | - Chia: `/` 60 | - Lấy lũy thừa: `^` 61 | - Lấy số dư: `%%` 62 | 63 | Hai phép tính cuối cùng có thể giải thích như sau: 64 | 65 | - Phép tính `^` đưa số bên trái lên lũy thừa bậc số bên phải của nó, ví dụ `3^2`bằng 9. 66 | - Phép tính `%%` trả lại phần dư của phép chia số bên trái cho số bên phải, ví dụ `5 %% 3` bằng 2. 67 | 68 | Với kiến thức trên, bạn hãy dựa vào hướng dẫn dưới đây để hoàn thành bài tập thực hành. 69 | 70 | *** =instructions 71 | - Gõ `2^5` trong trình soạn thảo để tính lũy thừa bậc 5 của 2. 72 | - Gõ `28 %% 6` để tính số dư của phép chia 28 cho 6. 73 | - Nhấn nút "Submit Answer" và xem kết quả của R trong console. 74 | - Chú ý là dấu `#` được dùng để thêm chú giải trong R. 75 | 76 | *** =hint 77 | Một ví dụ khác của phép tính tìm phần dư: `9 %% 2` bằng `1`. 78 | 79 | *** =pre_exercise_code 80 | ```{r} 81 | # no pec 82 | ``` 83 | 84 | *** =sample_code 85 | ```{r} 86 | # Phép cộng 87 | 5 + 5 88 | 89 | # Phép trừ 90 | 5 - 5 91 | 92 | # Phép nhân 93 | 3 * 5 94 | 95 | # Phép chia 96 | (5 + 5) / 2 97 | 98 | # Lấy lũy thừa 99 | 100 | 101 | # Lấy số dư 102 | 103 | ``` 104 | 105 | *** =solution 106 | ```{r} 107 | # Phép cộng 108 | 5 + 5 109 | 110 | # Phép trừ 111 | 5 - 5 112 | 113 | # Phép nhân 114 | 3 * 5 115 | 116 | # Phép chia 117 | (5 + 5) / 2 118 | 119 | # Lấy lũy thừa 120 | 2 ^ 5 121 | 122 | # Lấy số dư 123 | 28 %% 6 124 | ``` 125 | 126 | *** =sct 127 | ```{r} 128 | msg = "Xin đừng xóa các phép tính mẫu khác!" 129 | test_output_contains("2^5", incorrect_msg = "Phép lấy lũy thừa chưa chính xác. Hãy viết `2 ^ 5` trên một dòng mới.") 130 | test_output_contains("28 %% 6", incorrect_msg = "Phép lấy số dư có vẻ chưa đúng. Hãy viết `28 %% 6` trên một dòng mới.") 131 | success_msg("Tuyệt vời! Hãy sang bài tập tiếp theo.") 132 | ``` 133 | 134 | 135 | --- type:NormalExercise xp:100 skills:1 key:5f200ffd43 136 | ## Bài tập về biến 137 | 138 | Một trong những khái niệm cơ bản trong lập trình thống kê là khái niệm **biến**. 139 | 140 | Bạn có thể sử dụng một biến để chứa một giá trị (ví dụ: 4) hoặc một đối tượng (ví dụ như mô tả của một hàm số) trong R. Sau đó, nếu muốn sử dụng giá trị hoặc đối tượng này, bạn chỉ cần gọi tên của biến đó. 141 | 142 | Bạn có thể gán giá trị 4 cho biến `my_var`với câu lệnh 143 | 144 | ``` 145 | my_var <- 4 146 | ``` 147 | 148 | *** =instructions 149 | Đến lượt bạn rồi đấy: hãy viết tiếp câu lệnh trong editor để gán giá trị 42 cho biến `x` . Nhấn nút Submit Answer'. Khi bạn yêu cầu R hiển thị giá trị của `x`, bạn sẽ nhận được giá trị 42. 150 | 151 | *** =hint 152 | Trong phần thực hành, chúng ta đã gán giá trị 4 cho `my_variable`. Sử dụng câu lệnh giống hệt vậy trong editor, chỉ thay đổi ở việc gán giá trị 42 cho biến `x`. 153 | 154 | *** =pre_exercise_code 155 | ```{r} 156 | # no pec 157 | ``` 158 | 159 | *** =sample_code 160 | ```{r} 161 | # Gán giá trị 42 cho x 162 | x <- 163 | 164 | # Hiển thị giá trị của biến x 165 | x 166 | ``` 167 | 168 | *** =solution 169 | ```{r} 170 | # Gán giá trị 42 cho x 171 | x <- 42 172 | 173 | #Hiển thị giá trị của biến x 174 | x 175 | ``` 176 | 177 | *** =sct 178 | ```{r} 179 | test_object("x", undefined_msg = "Bạn cần định nghĩa `x`.", 180 | incorrect_msg = "Nhớ gán đúng giá trị cho `x`.") 181 | success_msg("Làm tốt lắm! Bạn có để ý thấy R không hiển thị giá trị của biến cho console trong bài tập vừa rồi? `x <- 42` không cho kết quả gì cả, bởi vì R đã mặc định rằng bạn không cần biến này ngay. Nếu không thì bạn cũng chẳng gán giá trị cho một biến làm gì, đúng không? Sang bài tập tiếp theo nhé!") 182 | ``` 183 | 184 | 185 | --- type:NormalExercise xp:100 skills:1 key:c5944b90eb 186 | ## Bài tập về biến (2) 187 | 188 | Giả dụ bạn có một cái làn hoa quả trong đó có 5 quả táo. Bạn muốn gán số lượng táo trong một biến tên là `my_apples`. 189 | 190 | *** =instructions 191 | - Gõ câu lệnh sau đây vào trình soạn thảo: `my_apples <- 5`. `my_apples` sẽ được gán giá trị là 5. 192 | - Gõ: `my_apples` dưới chú thích thứ hai để hiển thị ra giá trị của `my_apples`. 193 | - Nhấn nút 'Submit Answer', và theo dõi trong console. Bạn sẽ thấy số 5 được hiển thị. Điều này chứng tỏ R đã gắn biến `my_apples` cho giá trị 5. 194 | 195 | *** =hint 196 | Hãy nhớ là nếu muốn gán một số hay một đối tượng cho một biến trong R, bạn cần dùng dấu gán `<-`. Ngoài ra bạn cũng có thể dùng `=`, nhưng `<-` vẫn được sử dụng thường xuyên hơn. 197 | 198 | *** =pre_exercise_code 199 | ```{r} 200 | # no pec 201 | ``` 202 | 203 | *** =sample_code 204 | ```{r} 205 | # Gán giá trị 5 cho biến my_apples 206 | 207 | 208 | # Hiển thị giá trị của biến my_apples 209 | 210 | ``` 211 | 212 | *** =solution 213 | ```{r} 214 | # Gán giá trị 5 cho biến my_apples 215 | my_apples <- 5 216 | 217 | # Hiển thị ra giá trị của biến my_apples 218 | my_apples 219 | ``` 220 | 221 | *** =sct 222 | ```{r} 223 | test_object("my_apples", 224 | undefined_msg = "Hãy định nghĩa `my_apples`.", 225 | incorrect_msg = "Hãy gán đúng giá trị cho biến `my_apples`.") 226 | test_output_contains("my_apples", incorrect_msg = "Bạn đã yêu cầu R hiển thị biến `my_apples` ra console chưa?") 227 | success_msg("Tuyệt! Sang bài tập tiếp theo!") 228 | ``` 229 | 230 | 231 | --- type:NormalExercise xp:100 skills:1 key:1c1bd25045 232 | ## Bài tập về biến (3) 233 | 234 | Giỏ hoa quả ngon nào cũng phải có cam, nên bạn quyết định thêm 6 quả cam. Là một chuyên viên phân tích số liệu, phản xạ tức thì của bạn là tạo một biến tên là `my_oranges` và gán giá trị 6 cho biến này. Tiếp đến, bạn muốn tính tổng số hoa quả bạn có. Vì bạn đã đặt tên cho các giá trị này, bạn có thể tự tin viết câu lệnh: 235 | 236 | ``` 237 | my_apples + my_oranges 238 | ``` 239 | 240 | *** =instructions 241 | - Gán giá trị 6 cho biến `my_oranges`. 242 | - Cộng hai biến `my_apples` và `my_oranges`, sau đó yêu cầu R hiển thị ra kết quả. 243 | - Gán kết quả tính toán của phép tính cộng `my_apples` và `my_oranges` cho một biến mới là `my_fruit`. 244 | 245 | *** =hint 246 | `my_fruit` là tổng của `my_apples` và `my_oranges`. Dùng dấu `+` để cộng tổng của 2 biến đó, sau đó dùng dấu `<-` để gán kết quả cuối cùng cho `my_fruit`. 247 | 248 | *** =pre_exercise_code 249 | ```{r} 250 | # no pec 251 | ``` 252 | 253 | *** =sample_code 254 | ```{r} 255 | # Gán các giá trị đúng cho biến my_apples và my_oranges 256 | my_apples <- 5 257 | 258 | 259 | # Cộng tổng 2 biến 260 | 261 | 262 | # Tạo biến my_fruit 263 | 264 | ``` 265 | 266 | *** =solution 267 | ```{r} 268 | # Gán các giá trị đúng cho biến my_apples và my_orange 269 | my_apples <- 5 270 | my_oranges <- 6 271 | 272 | # Cộng tổng 2 biến 273 | my_apples + my_oranges 274 | 275 | # Tạo biến my_fruit 276 | my_fruit <- my_apples + my_oranges 277 | ``` 278 | 279 | *** =sct 280 | ```{r} 281 | test_object("my_apples", incorrect_msg = "Giữ lại dòng lệnh dùng để gán giá trị 5 cho biến `my_apples`.") 282 | test_object("my_oranges", incorrect_msg = "Giữ lại dòng lệnh dùng để gán giá trị 6 cho biến `my_oranges`.") 283 | test_output_contains("my_apples + my_oranges", 284 | incorrect_msg = "Hãy nhớ hiển thị ra kết quả của phép tính cộng giữa `my_apples` và `my_oranges`. Câu lệnh mẫu trong phần mô tả thực ra đã làm lộ kết quả của phép tính này!") 285 | msg <- "Bạn đã dùng lệnh `my_fruit <- my_apples + my_oranges` để tạo biến `my_fruit` chưa?" 286 | test_object("my_fruit", undefined_msg = msg, incorrect_msg = msg) 287 | success_msg("Tốt lắm! Lợi thế rất lớn của việc sử dụng các biến để tính toán nằm ở khả năng tái sử dụng. Nếu bạn gán lại biến `my_apples` để nó bằng 12 chứ không bằng 5 nữa và chạy lại câu lệnh, `my_fruit` cũng sẽ được cập nhật ngay lập tức. Sang bài tiếp theo nhé.") 288 | ``` 289 | 290 | 291 | --- type:NormalExercise xp:100 skills:1 key:915fcc7c99 292 | ## Táo và Cam 293 | 294 | Ai cũng bảo không nên lẫn lộn táo và cam với nhau. Nhưng bạn vừa làm thế đấy thôi, đúng không :-)? Trong bài tập vừa rồi, cả hai biến `my_apples` và `my_oranges` đều chứa số. Dấu `+` trong R chỉ sử dụng được khi các biến đều chứa số. Nếu bạn thật sự muốn cộng tổng của "apples" và "oranges", và gán một giá trị chữ cho biến `my_oranges` (xem trình soạn thảo), R sẽ nghĩ bạn muốn gán tổng của một biến số và một biến chữ cho biến `my_fruit`. Điều này là không thể. 295 | 296 | *** =instructions 297 | - Nhấn nút 'Submit Answer' và đọc câu thông báo lỗi. Bạn cần hiểu rõ tại sao lại có lỗi. 298 | - Chỉnh lại câu lệnh để R hiển bạn có 6 quả cam, và vì vậy giỏ hoa của của bạn có số lượng hoa quả là 11. 299 | 300 | *** =hint 301 | Bạn cần gán giá trị số`6` cho biến `my_oranges` chứ không phải là giá trị chữ `"six"`. Bạn có thấy dấu ngoặc kép được dùng để thể hiện `"six"` là một giá trị chữ? 302 | 303 | *** =pre_exercise_code 304 | ```{r} 305 | # no pec 306 | ``` 307 | 308 | *** =sample_code 309 | ```{r} 310 | # Gán giá trị cho biến my_apples 311 | my_apples <- 5 312 | 313 | # Gán lại giá trị đúng cho my_oranges 314 | my_oranges <- "six" 315 | 316 | # Tạo và hiển thị biến my_fruit 317 | my_fruit <- my_apples + my_oranges 318 | my_fruit 319 | ``` 320 | 321 | *** =solution 322 | ```{r} 323 | # Gán giá trị cho biến my_apples 324 | my_apples <- 5 325 | 326 | # Gán lại giá trị đúng cho my_oranges 327 | my_oranges <- 6 328 | 329 | # Tạo và hiển thị biến my_fruit 330 | my_fruit <- my_apples + my_oranges 331 | my_fruit 332 | ``` 333 | 334 | *** =sct 335 | ```{r} 336 | test_error(incorrect_msg = "Bạn cần gán cho `my_oranges` một giá trị số, chứ không phải là một chuỗi từ!") 337 | test_object("my_apples", incorrect_msg = "Hãy nhớ là biến `my_apples` vẫn mang giá trị `5`.") 338 | test_object("my_oranges", incorrect_msg = "Hãy làm sao để `my_oranges` bằng `6`.") 339 | test_object("my_fruit", incorrect_msg = "Giá trị của biến `my_fruit` chưa đúng. Nó phải bằng 11, là tổng của `my_apples` và`my_oranges`.") 340 | test_output_contains("my_fruit", incorrect_msg = "Đừng bỏ dòng lệnh dùng để hiển thị giá trị của `my_fruit`.") 341 | success_msg("Tuyệt lắm, cố gắng giữ phong độ nhé! Sang bài tập tiếp theo nào.") 342 | ``` 343 | 344 | 345 | --- type:NormalExercise xp:100 skills:1 key:0f23107394 346 | ## Các loại dữ liệu cơ bản trong R 347 | 348 | R có thể xử lý nhiều loại dữ liệu khác nhau. Chúng ta sẽ bắt đầu với các loại dữ liệu cơ bản nhất: 349 | 350 | - Các giá trị thập phân ví dụ như `4.5`được gọi là **số** (numeric) 351 | - Các số tự nhiên ví dụ như `4` được gọi là **số nguyên**. Các số nguyên cũng nằm trong tập số (integers) 352 | - Các giá trị lôgic (`TRUE` hoặc `FALSE`) được gọi là **giá trị lôgic** (logical) 353 | - Các giá trị chữ hoặc chuỗi chữ được gọi là **ký tự** (characters) 354 | 355 | Chú ý: Kiểu dữ liệu nằm trong dấu ngoặc kép là kiểu ký tự (characters) 356 | 357 | *** =instructions 358 | Thay đổi giá trị của các biến sau đây: 359 | 360 | - Biến `my_numeric` thành `42`. 361 | - Biến `my_character` thành `"universe"`. Dấu ngoặc kép thể hiện `"universe"` là một ký tự. 362 | - Biến`my_logical` thành `FALSE`. 363 | 364 | Hãy nhớ là R phân biệt chữ thường và chữ hoa! 365 | 366 | *** =hint 367 | Thay đổi các giá trị trong editor thành các giá trị được cho trong bài tập. Ví dụ: 368 | `my_numeric <- 42` được dùng để gán giá trị 42 cho biến `my_numeric`. 369 | 370 | *** =pre_exercise_code 371 | ```{r} 372 | # no pec 373 | ``` 374 | 375 | *** =sample_code 376 | ```{r} 377 | # Thay đổi giá trị của my_numeric thành 42 378 | my_numeric <- 42.5 379 | 380 | # Thay đổi giá trị của my_character thành "universe" 381 | my_character <- "some text" 382 | 383 | # Thay đổi giá trị của my_logical thành FALSE 384 | my_logical <- TRUE 385 | ``` 386 | 387 | *** =solution 388 | ```{r} 389 | # Thay đổi giá trị của my_numeric thành 42 390 | my_numeric <- 42 391 | 392 | # Thay đổi giá trị của my_character thành "universe 393 | my_character <- "universe" 394 | 395 | # Thay đổi giá trị của my_logical thành FALSE 396 | my_logical <- FALSE 397 | ``` 398 | 399 | *** =sct 400 | ```{r} 401 | test_object("my_numeric", incorrect_msg = "Bạn đã sửa lại giá trị của `my_numeric` để nó chứa 42?") 402 | test_object("my_character", incorrect_msg = "Bạn đã sửa lại chính xác giá trị của `my_character` thành `\"universe\"` chưa? Đừng quên thêm dấu ngoặc kép nhé!") 403 | test_object("my_logical", incorrect_msg = "Bạn đã sửa lại chính xác giá trị của `my_logical` thành `FALSE` chưa? Nhớ viết hoa tất cả các chữ trong `FALSE`nhé!") 404 | success_msg("Giỏi lắm! Sang bài tập tiếp theo thôi.") 405 | ``` 406 | 407 | 408 | --- type:NormalExercise xp:100 skills:1 key:99b549229d 409 | ## Dữ liệu kia thuộc loại gì nhỉ? 410 | 411 | Bạn có nhớ là lúc bạn tính tổng `5 + "six"`, bạn nhận lại thông báo lỗi do định dạng dữ liệu không thống nhất? Bạn có thể tránh các lỗi kiểu này bằng cách kiểm tra trước loại dữ liệu của biến. Để làm điều này, bạn dùng hàm`class()`. Hãy xem ví dụ được thể hiện trong phần lệnh bên phải màn hình. 412 | 413 | *** =instructions 414 | Hoàn thành phần lệnh trong trình soạn thảo, đồng thời hiển thị thông tin loại dữ liệu của `my_character` và `my_logical`. 415 | 416 | *** =hint 417 | Câu lệnh để hiển thị thông tin loại dữ liệu của `my_numeric` đã được cho sẵn; hãy làm giống vậy cho `my_character` và `my_logical`. 418 | 419 | *** =pre_exercise_code 420 | ```{r} 421 | # no pec 422 | ``` 423 | 424 | *** =sample_code 425 | ```{r} 426 | # Gán giá trị cho các biến thuộc nhiều loại dữ liệu khác nhau: 427 | my_numeric <- 42 428 | my_character <- "universe" 429 | my_logical <- FALSE 430 | 431 | # Kiểm tra loại dữ liệu của my_numeric 432 | class(my_numeric) 433 | 434 | # Kiểm tra loại dữ liệu của my_character 435 | 436 | 437 | # Kiểm tra loại dữ liệu của my_logical 438 | 439 | ``` 440 | 441 | *** =solution 442 | ```{r} 443 | # Gán giá trị cho các biến thuộc nhiều loại dữ liệu khác nhau: 444 | my_numeric <- 42 445 | my_character <- "universe" 446 | my_logical <- FALSE 447 | 448 | # Kiểm tra loại dữ liệu của my_numeric 449 | class(my_numeric) 450 | 451 | # Kiểm tra loại dữ liệu của my_character 452 | class(my_character) 453 | 454 | # Kiểm tra loại dữ liệu của my_logical 455 | class(my_logical) 456 | ``` 457 | 458 | *** =sct 459 | ```{r} 460 | msg <- "Đừng sửa lại giá trị của các biến!" 461 | lapply(c("my_numeric", "my_character", "my_logical"), test_object, undefined_msg = msg, incorrect_msg = msg) 462 | patt <- "Bạn đã thêm câu lệnh `class(%1$s)` để hiển thị loại dữ liệu của `%1$s` chưa?" 463 | test_output_contains("class(my_numeric)", 464 | incorrect_msg = "Đừng xóa câu lệnh hiển thị loại dữ liệu của `my_numeric`.") 465 | test_output_contains("class(my_character)", 466 | incorrect_msg = sprintf(patt, "my_character")) 467 | test_output_contains("class(my_logical)", 468 | incorrect_msg = sprintf(patt, "my_logical")) 469 | success_msg("Chúc mừng! Bạn đã hoàn thành bài tập cuối cùng trong chương này. Hãy sang chương tiếp theo để tìm hiểu về thế giới của những véc-tơ!") 470 | ``` 471 | 472 | 473 | 474 | -------------------------------------------------------------------------------- /chapter4.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : Chương 4 3 | title : Factors 4 | description : Trong rất nhiều trường hợp, dữ liệu có giá trị nằm trong một nhóm hữu hạn các giá trị cho trước. Ví dụ, giới tính có giá trị nam hoặc nữ. Trong R, các biến có loại này được gọi là factor. Các biến factor đóng vai trò rất quan trọng trong quá trình phân tích dữ liệu. Do đó, chúng ta sẽ cùng học cách tạo và xử lý các biến factor trong bài giảng dưới đây. 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:05273321916d99bb9c0deadf75c6834d25a47244 7 | ## Factor là gì và tại sao chúng ta lại sử dụng chúng? 8 | 9 | Trong chương này, chúng ta sẽ cùng nhau tìm hiểu các biến **factors**. 10 | 11 | Thuật ngữ factor được sử dụng cho loại dữ liệu dùng trong phân tích thống kê được sử dụng để lưu trữ các nhóm. Sự khác biệt cơ bản giữa biến nhóm và biến số là ở chỗ, các giá trị của biến nhóm thuộc một **nhóm hữu hạn các giá trị cho trước**. Trong khi đó, biến định dạng số có thể có vô số các giá trị (trong một số tài liệu tiếng Việt, còn được gọi là **biến yếu tố**). 12 | 13 | Khi phân tích dữ liệu, việc xác định được đang phân tích biến số hay biến nhóm (factor) là rất quan trọng, bởi lẽ các mô hình phân tích thống kê sẽ xử lý hai định dạng dữ liệu này khác nhau (các bạn sẽ thấy rõ điều nay trong các phần tiếp theo). 14 | 15 | Một ví dụ điển hình của biến nhóm là biến 'Giới tính'. Mỗi cá nhân có thể có giới tính là "Nam" hoặc "Nữ". Do đó, "Nam" và "Nữ" là hai giá trị của biến định dạng nhóm "Giới tính", và bất kỳ quan sát nào cũng có thể gán một trong hai giá trị - "Nam" hoặc "Nữ" 16 | 17 | *** =instructions 18 | Gán biến `theory` giá trị của `factors for categorical variables`. 19 | 20 | *** =hint 21 | Sử dụng ký tự gán như thông thường (`<-`); 22 | 23 | *** =pre_exercise_code 24 | ```{r} 25 | # no pec 26 | ``` 27 | 28 | *** =sample_code 29 | ```{r} 30 | # Gán nội dung "factors for categorical variables" cho biến theory 31 | ``` 32 | 33 | *** =solution 34 | ```{r} 35 | # Gán nội dung "factors for categorical variables" cho biến theory 36 | theory <- "factors for categorical variables" 37 | ``` 38 | 39 | *** =sct 40 | ```{r} 41 | test_object("theory", incorrect_msg = "Kiểm tra lại chuỗi giá trị `\"factors for categorical variables\"` gán cho biến `theory`. Lưu ý rằng R có phân biệt chữ hoa và chữ thường."); 42 | success_msg("Rất tốt! Bạn đã sẵn sàng chưa? Tiếp tục bài tập tiếp theo nhé!") 43 | ``` 44 | 45 | 46 | --- type:NormalExercise xp:100 skills:1 key:6cc21c842b075347926bb1b244782213df32e370 47 | ## Factor là gì và tại sao chúng ta lại sử dụng chúng? (2) 48 | 49 | Để tạo biến factor trong R, bạn có thể sử dụng hàm [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor). Đầu tiên, bạn cần phải tạo một véc-tơ chứa tất cả các quan sát thuộc một nhóm các giá trị hữu hạn. Ví dụ, `gender_vector`chưá 5 quan sát độc lập: 50 | 51 | 52 | ``` 53 | gender_vector <- c("Male","Female","Female","Male","Male") 54 | ``` 55 | 56 | Trong trường hợp này, véc-tơ có hai giá trị: "Male" và "Female" (trong R còn được gọi là **'factor levels'**). 57 | 58 | Hàm [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor) sẽ chuyển đổi giá trị của véc-tơ thành dạng factor: 59 | 60 | ``` 61 | factor_gender_vector <- factor(gender_vector) 62 | ``` 63 | 64 | *** =instructions 65 | - Chuyển véc-tơ dạng character `gender_vector` thành véc-tơ có dạng `factor()` và gán kết quả cho véc-tơ `factor_gender_vector` 66 | - Hiển thị giá trị của véc-tơ `factor_gender_vector` và chắc chắc rằng R hiển thị các giá trị của factor bên dưới khu vực hiển thị giá trị của véc-tơ 67 | 68 | *** =hint 69 | Sử dụng hàm [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor) với véc-tơ `gender_vector`. Xem ví dụ và tài liệu đi kèm. 70 | *** =pre_exercise_code 71 | ```{r} 72 | # no pec 73 | ``` 74 | 75 | *** =sample_code 76 | ```{r} 77 | # Tạo gender_vector 78 | gender_vector <- c("Male", "Female", "Female", "Male", "Male") 79 | 80 | # Chuyển đổi gender_vector thành dạng factor 81 | factor_gender_vector <- 82 | 83 | # Hiển thị véc-tơ factor_gender_vector 84 | 85 | ``` 86 | 87 | *** =solution 88 | ```{r} 89 | # Tạo gender_vector 90 | gender_vector <- c("Male", "Female", "Female", "Male", "Male") 91 | 92 | # Chuyển đổi gender_vector thành dạng factor 93 | factor_gender_vector <- factor(gender_vector) 94 | 95 | # Hiển thị véc-tơ factor_gender_vector 96 | factor_gender_vector 97 | ``` 98 | 99 | *** =sct 100 | ```{r} 101 | test_object("factor_gender_vector", 102 | incorrect_msg = "Bạn đã gán gán factor `gender_vector` cho véc-tơ `factor_gender_vector` chưa?") 103 | test_output_contains("factor_gender_vector", incorrect_msg = "Nhớ hiển thị véc-tơ `factor_gender_vector`!") 104 | success_msg("Rất tốt! Nếu bạn muốn tìm hiểu thêm về hàm `factor()`, gõ lệnh `?factor` trên màn hình console. Lệnh này sẽ mở trang tài liệu chứa các thông tin về hàm 'factor'. Tiếp tục làm bài tập tiếp theo nhé."); 105 | ``` 106 | 107 | 108 | --- type:NormalExercise xp:100 skills:1 key:5bd4f50afc2c2dbc881e16b8ca94ca56960dff42 109 | ## Factor là gì và tại sao chúng ta lại sử dụng chúng? (3) 110 | 111 | Biến yếu tố (nhóm) có 2 loại: **biến yếu tố không sắp xếp thứ tự** và **biến yếu tố có sắp xếp thứ tự** (nominal & cardinal variable) 112 | 113 | Đối với biến yếu tố không sắp xếp thứ tự (nominal variable), ta không thể nói rằng "giá trị này tốt hơn giá trị kia". Ví dụ, khi sử dụng véc-tơ `animals_vector` với các giá trị là `"Elephant"`,`"Giraffe"`, `"Donkey"` và `"Horse"`, ta không thể nói loài nào tốt hơn hay kém hơn loài nào (Hẳn một vài bạn sẽ không đồng ý ;-) ). 114 | 115 | Ngược lại, biến yếu tố có sắp xếp thứ tự cho phép sắp xếp các giá trị của biến theo thứ tự. Ví dụ, đối với véc-tơ `temperature_vector` với các giá trị: `"Low"`, `"Medium"` và `"High"`, giá trị `"High"` có giá trị lớn hơn `"Medium"` và `"Medium"` có giá trị lớn hơn `"Low"`. 116 | 117 | *** =instructions 118 | 119 | Ấn 'Submit Answer' để kiểm tra cách R triển khai và hiển thị các biến yếu tố có sắp xếp và không sắp xếp thứ tự. Đừng lo nếu bạn chưa hiểu hết các đoạn code, chúng ta sẽ học trong các phần tiếp theo. 120 | 121 | *** =hint 122 | Ấn nút 'Submit Answer' và xem màn hình hiển thị. Lưu ý cách thức R hiển thị thứ tự của các biến yếu tố có sắp xếp thứ tự (ordinal) 123 | 124 | *** =pre_exercise_code 125 | ```{r} 126 | # no pec 127 | ``` 128 | 129 | *** =sample_code 130 | ```{r} 131 | # Các loài động vật 132 | animals_vector <- c("Elephant", "Giraffe", "Donkey", "Horse") 133 | factor_animals_vector <- factor(animals_vector) 134 | factor_animals_vector 135 | 136 | # Nhiệt độ 137 | temperature_vector <- c("High", "Low", "High","Low", "Medium") 138 | factor_temperature_vector <- factor(temperature_vector, order = TRUE, levels = c("Low", "Medium", "High")) 139 | factor_temperature_vector 140 | ``` 141 | 142 | *** =solution 143 | ```{r} 144 | # Các loài động vật 145 | animals_vector <- c("Elephant", "Giraffe", "Donkey", "Horse") 146 | factor_animals_vector <- factor(animals_vector) 147 | factor_animals_vector 148 | 149 | # Nhiệt độ 150 | temperature_vector <- c("High", "Low", "High","Low", "Medium") 151 | factor_temperature_vector <- factor(temperature_vector, order = TRUE, levels = c("Low", "Medium", "High")) 152 | factor_temperature_vector 153 | ``` 154 | 155 | *** =sct 156 | ```{r} 157 | msg <- "Không thay đổi bất kỳ điều gì ở các câu lệnh mẫu. Ấn nút Submit Answer để xem lời giải." 158 | test_object("animals_vector", undefined_msg = msg, incorrect_msg = msg) 159 | test_object("temperature_vector", undefined_msg = msg, incorrect_msg = msg) 160 | test_object("factor_animals_vector", undefined_msg = msg, incorrect_msg = msg) 161 | test_output_contains("factor_animals_vector", incorrect_msg = msg) 162 | test_object("factor_temperature_vector", undefined_msg = msg, incorrect_msg = msg) 163 | test_output_contains("factor_temperature_vector", incorrect_msg = msg) 164 | success_msg("Bạn đã nắm được kiến thức trong bài tập này? Tuyệt vời! Hãy tiếp tục bài tập tiếp theo để hiểu rõ hơn về factor levels.") 165 | ``` 166 | 167 | 168 | --- type:NormalExercise xp:100 skills:1 key:1aa698978d32d1a0befa4700d7da85a648e1d69e 169 | ## Các giá trị của factor (factor levels) 170 | 171 | Khi mới tiếp cận dữ liêu, các bạn hẳn sẽ nhận thấy rằng các factor chứa một số giá trị nhất định. Tuy nhiên, đôi khi ta muốn đổi tên của các giá trị này nhằm phục vụ quá trình phân tích dữ liệu. R cho phép bạn thực hiện quá trình này với hàm [`levels()`](http://www.rdocumentation.org/packages/base/functions/levels): 172 | 173 | ``` 174 | levels(factor_vector) <- c("name1", "name2",...) 175 | ``` 176 | 177 | 178 | Một ví dụ điển hình để giải thích quá trình này là sử dụng bảng hỏi. Khi thu thập ý kiến, một câu hỏi điển hình là giới tính của người được hỏi. Hẳn các bạn vẫn còn nhớ đây là biến factor có hai giá `"M"` và `"F"`. 179 | 180 | ``` 181 | survey_vector <- c("M", "F", "F", "M", "M") 182 | ``` 183 | 184 | Tiếp đó, khi bắt đầu phân tích dữ liệu, quan tâm chính của bạn sẽ là giữ được cái nhìn tổng quan của tất cả các biến cũng như ý nghĩa của chúng. Khi đó, để giúp quá trình phân tích được dễ dàng hơn, bạn thường sẽ muốn đổi các giá trị của factor thành `"Male"` và `"Female"` (nam và nữ) thay cho giá trị `"M"` và `"F"` 185 | 186 | **Lưu ý**: Thứ tự của các giá trị trong biến factor rất quan trọng trong quá trình phân tích. Nếu gõ `levels(factor_survey_vector)`, bạn sẽ thấy kết quả hiển thị là `[1] "F" "M"`. Nếu bạn không xác định rõ giá trị của facotr, `R` sẽ tự động gán chúng theo thứ tự bảng chữ cái. Để gán `"F"` thành `"Female"` và `"M"` thành `"Male"`, giá trị của factor cần được gán thành `c("Female", "Male")` theo thứ tự 187 | 188 | *** =instructions 189 | - Kiểm tra đoạn code xây dựng giá trị của factor từ `survey_vector`. Bạn nên sử dụng `factor_survey_vector` trong phần bài giảng tiếp theo. 190 | - Đổi thứ thự các giá trị của `factor_survey_vector` thành `c("Female", "Male")`. Lưu ý thứ tự các giá trị trong vector 191 | 192 | 193 | *** =hint 194 | Lưu ý thứ tự các giá trị trong factor. Bạn có thể kiểm tra thứ tự của giá trị trong factor bằng cách sử dụng cầu lệnh `levels(factor_survey_vector)`. 195 | 196 | 197 | *** =pre_exercise_code 198 | ```{r} 199 | # no pec 200 | survey_vector <- c("M", "F", "F", "M", "M") 201 | factor_survey_vector <- factor(survey_vector) 202 | ``` 203 | 204 | *** =sample_code 205 | ```{r} 206 | # Xây dựng véc-tơ factor_survey_vector 207 | survey_vector <- c("M", "F", "F", "M", "M") 208 | factor_survey_vector <- factor(survey_vector) 209 | 210 | # Xác định thứ tự của factor_survey_vector 211 | levels(factor_survey_vector) <- 212 | 213 | factor_survey_vector 214 | ``` 215 | 216 | *** =solution 217 | ```{r} 218 | # Xây dựng véc-tơ factor_survey_vector 219 | survey_vector <- c("M", "F", "F", "M", "M") 220 | factor_survey_vector <- factor(survey_vector) 221 | 222 | # Xác định thứ tự của factor_survey_vector 223 | levels(factor_survey_vector) <- c("Female", "Male") 224 | 225 | factor_survey_vector 226 | ``` 227 | 228 | *** =sct 229 | ```{r} 230 | msg = "Đừng thay đổi định nghĩa của véc-tơ `survey_vector`!" 231 | test_object("survey_vector", undefined_msg = msg, incorrect_msg = msg) 232 | msg = "Không chỉnh sửa các câu lệnh tạo factor." 233 | test_function("factor", "x", not_called_msg = msg, incorrect_msg = msg) 234 | test_object("factor_survey_vector", eq_condition = "equal", 235 | incorrect_msg = paste("Bạn có gán giá trị chính xác của factor cho `factor_survey_vector` chưa? Sử dụng hàm `levels(factor_survey_vector) <- c(\"Female\", \"Male\")`. Nhớ rằng R có phân biệt chữ in hoa và chữ in thường nhé")) 236 | success_msg("Tuyệt vời! Tiếp tục làm bài tập tiếp theo nhé.") 237 | ``` 238 | 239 | 240 | --- type:NormalExercise xp:100 skills:1 key:a549f13c0644ccc89cd39a10aa48706754637ed0 241 | ## Tóm tắt giá trị của factor 242 | 243 | 244 | Sau khi kết thúc khóa học này một trong những câu lệnh bạn sẽ hay dùng nhất là [`summary()`](http://www.rdocumentation.org/packages/base/functions/summary). Câu lệnh này cho phép bạn nhìn được tổng quan các biến trong tập dữ liệu của mình: 245 | 246 | ``` 247 | summary(my_var) 248 | ``` 249 | 250 | Quay lại với ví dụ về bảng hỏi ở phần trước, bạn có lẽ sẽ muốn kiểm tra xem có bao nhiêu giá trị `"Male"` và `"Female"`. Hàm [`summary()`](http://www.rdocumentation.org/packages/base/functions/summary) sẽ trả lời cho câu hỏi trên của bạn. 251 | 252 | *** =instructions 253 | Sử dụng hàm [`summary()`](http://www.rdocumentation.org/packages/base/functions/summary) đối với `survey_vector` và `factor_survey_vector`. Giải thích kết quả của cả 2 véc-tơ. Liệu rằng kết quả đều có giá trị như nhau trong cả hai trường hợp trên? 254 | 255 | *** =hint 256 | Gọi hàm [`summary()`](http://www.rdocumentation.org/packages/base/functions/summary) đối với `survey_vector` và `factor_survey_vector`, đơn giản vậy thôi! 257 | 258 | *** =pre_exercise_code 259 | ```{r} 260 | # no pec 261 | ``` 262 | 263 | *** =sample_code 264 | ```{r} 265 | # Tạo véc-tơ factor_survey_vector 266 | survey_vector <- c("M", "F", "F", "M", "M") 267 | factor_survey_vector <- factor(survey_vector) 268 | levels(factor_survey_vector) <- c("Female", "Male") 269 | factor_survey_vector 270 | 271 | # Tổng hợp kết quả từ véc-tơ survey_vector 272 | 273 | 274 | # Gọi kết quả tổng hợp từ véc-tơ factor_survey_vector 275 | 276 | ``` 277 | 278 | *** =solution 279 | ```{r} 280 | # Tạo véc-tơ factor_survey_vector 281 | survey_vector <- c("M", "F", "F", "M", "M") 282 | factor_survey_vector <- factor(survey_vector) 283 | levels(factor_survey_vector) <- c("Female", "Male") 284 | factor_survey_vector 285 | 286 | # Tổng hợp kết quả từ véc-tơ survey_vector 287 | summary(survey_vector) 288 | 289 | # Gọi kết quả tổng hợp từ véc-tơ factor_survey_vector 290 | summary(factor_survey_vector) 291 | ``` 292 | 293 | *** =sct 294 | ```{r} 295 | msg = "Đừng thay đổi giá trị `survey_vector` và `factor_survey_vector`." 296 | test_object("survey_vector", undefined_msg = msg, incorrect_msg = msg) 297 | test_object("factor_survey_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 298 | msg <- "Bạn đã sử dụng hàm `summary()` chính xác chưa?" 299 | test_output_contains("summary(survey_vector)", incorrect_msg = sprintf(msg, "survey_vector")) 300 | test_output_contains("summary(factor_survey_vector)", incorrect_msg = sprintf(msg, "factor_survey_vector")) 301 | success_msg("Rất tốt! Hãy xem kết quả cuối cùng. Khi bạn gán giá trị `\"Male\"` và `\"Female\"` thành giá trị của factor trong `factor_survey_vector`, bạn đã cho phép R tính toán và hiển thị số lượng các giá trị trong mỗi biến.") 302 | ``` 303 | 304 | 305 | --- type:NormalExercise xp:100 skills:1 key:90ecc160d1ebf2f75bf53f9c3843fc1632bdd0a5 306 | ## Xác định giới tính 307 | 308 | Trong `factor_survey_vector`, chúng ta có một factor với hai giá trị: Male và Female. Nhưng làm thế nào R xác định được các giá trị này? Hay nói cách khác, R xác định thứ tự thế nào, Male hay Female? 309 | 310 | *** =instructions 311 | 312 | Đọc các câu lệnh trong editor và click 'Submit Answer' để xem giá trị nào, Male hay Female có giá trị hơn. 313 | 314 | *** =hint 315 | Ấn vào nút 'Submit Answer' để xem kết quả được hiển thị trên màn hình tương tác. 316 | 317 | *** =pre_exercise_code 318 | ```{r} 319 | # no pec 320 | ``` 321 | 322 | *** =sample_code 323 | ```{r} 324 | # Tạo véc-tơ factor_survey_vector 325 | survey_vector <- c("M", "F", "F", "M", "M") 326 | factor_survey_vector <- factor(survey_vector) 327 | levels(factor_survey_vector) <- c("Female", "Male") 328 | 329 | # Male 330 | male <- factor_survey_vector[1] 331 | 332 | # Female 333 | female <- factor_survey_vector[2] 334 | 335 | # Đánh giá các giá trị của giới tính: Male hay Female 'có giá trị hơn'? 336 | male > female 337 | ``` 338 | 339 | *** =solution 340 | ```{r} 341 | # Tạo véc-tơ factor_survey_vector 342 | survey_vector <- c("M", "F", "F", "M", "M") 343 | factor_survey_vector <- factor(survey_vector) 344 | levels(factor_survey_vector) <- c("Female", "Male") 345 | 346 | # Male 347 | male <- factor_survey_vector[1] 348 | 349 | # Female 350 | female <- factor_survey_vector[2] 351 | 352 | # Đánh giá các giá trị của giới tính: Male hay Female 'có giá trị hơn'? 353 | male > female 354 | ``` 355 | 356 | *** =sct 357 | ```{r} 358 | msg = "Không thay đổi các câu lệnh; chỉ ấn 'Submit Answer' và xem kết quả." 359 | test_object("survey_vector", undefined_msg = msg, incorrect_msg = msg) 360 | test_object("factor_survey_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 361 | test_object("male", undefined_msg = msg, incorrect_msg = msg) 362 | test_object("female", undefined_msg = msg, incorrect_msg = msg) 363 | test_output_contains("male > female", incorrect_msg = msg) 364 | success_msg("Hừm, hình như R không phân biệt giới tính. Hoặc ta cần thảo luận thêm vấn đề này sau vậy ;-).") 365 | ``` 366 | 367 | 368 | --- type:NormalExercise xp:100 skills:1 key:9ab0928916bf84ab225713a9a1ce40d9e322c6a0 369 | ## Factor có phân biệt thứ tự (1) 370 | 371 | Bời vì `"Male"` và `"Female"` là giá trị của biến factor không phân biệt thứ tự, nên R hiển thị thông báo với bạn rằng, không tồn tại phép toán lớn hơn trường hợp này. Như ta đã thấy trước đó, R gán các giá trị bằng nhau cho factor 372 | 373 | 374 | Tuy nhiên, không phải lúc nào cũng vậy! Đôi lúc bạn cần phải xử lý factor có phân biệt thứ tự. Trong trường hợp này, ta cần chắc chắn rằng ta đã khai báo các thông tin này với R. 375 | 376 | Giả sử rằng bạn đang hướng dẫn một nhóm nhiên cứu gồm có 5 chuyên viên phân tích dữ liệu, và rằng bạn muốn đánh giá quá trình nghiên cứu của họ. Để làm điều này, bạn cần đánh giá tốc độ làm việc của họ thành các giá trị `"slow"`, `"fast"` hay `"insane"`, và lưu kết quả trong véc-tơ `speed_vector`. 377 | 378 | *** =instructions 379 | Ở bước đầu tiên, ta cần gán giá trị `speed_vector`, biết rằng 380 | 381 | - Chuyên viên một làm nhanh (fast) 382 | - Chuyên viên hai làm chậm (slow) 383 | - Chuyên viên ba làm chậm (slow) 384 | - Chuyên viên bốn làm nhanh (fast) 385 | - Chuyên viên 5 làm nhanh khủng khiếp (insane) 386 | 387 | Ta chưa cần xác định các factor này ngay 388 | 389 | *** =hint 390 | Gán véc-tơ `speed_vector` một véc-tơ có giá trị, `"fast"`, `"slow"` ... 391 | 392 | *** =pre_exercise_code 393 | ```{r} 394 | # no pec 395 | ``` 396 | 397 | *** =sample_code 398 | ```{r} 399 | # Tạo véc-tơ speed_vector 400 | speed_vector <- 401 | ``` 402 | 403 | *** =solution 404 | ```{r} 405 | # Tạo véc-tơ speed_vector 406 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 407 | ``` 408 | 409 | *** =sct 410 | ```{r} 411 | test_object("speed_vector", 412 | incorrect_msg = "Đảm bảo rằng bạn đã gán các giá trị chính xác cho véc-tơ speed_vector. Không sử dụng các chữ in hoa!") 413 | success_msg("Làm rất tốt! Làm bài tập tiếp theo nào.") 414 | ``` 415 | 416 | 417 | --- type:NormalExercise xp:100 skills:1 key:279077d10248ce03d5f972939ef8576430a16683 418 | ## Factor có phân biệt thứ tự (2) 419 | 420 | `speed_vector` cần được chuyển thành dạng factor có phân biệt thứ tự. Hàm [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor) chuyển đổi `speed_vector` thành factor không phân biệt thứ tự. Để tạo một véc-tơ có thứ tự, bạn cần phải thêm vào hai tham số `ordered` và `levels`. 421 | 422 | ``` 423 | factor(some_vector, 424 | ordered = TRUE, 425 | levels = c("lev1", "lev2" ...)) 426 | ``` 427 | 428 | Bằng cách đặt tham số `ordered` thành `TRUE` trong hàm [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor), bạn đã chỉ ra rằng các giá trị trong factor được sắp xếp thứ tự. Tham số `levels` cho phép các giá trị của factor được sắp xếp theo đúng thứ tự. 429 | 430 | *** =instructions 431 | Từ véc-tơ `speed_vector`, tạo một véc-tơ có phân biệt thứ tự : `factor_speed_vector`. Đặt tham số `ordered` thành `TRUE`, và đặt `levels` thành `c("slow", "fast", "insane")`. 432 | 433 | *** =hint 434 | Sử dụng hàm [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor) để tạo `factor_speed_vector` dựa trên véc-tơ `speed_character_vector`. Tham số `ordered` cần được đặt thành `TRUE` bởi lẽ các giá trị này cần được sắp xếp theo thứ tự. Thêm vào đó, ta cần đặt `levels = c("slow", "fast", "insane")`. 435 | 436 | *** =pre_exercise_code 437 | ```{r} 438 | # no pec 439 | ``` 440 | 441 | *** =sample_code 442 | ```{r} 443 | # Tạo speed_vector 444 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 445 | 446 | # Chuyển véc-tơ speed_vector thành véc-tơ có phân biệt thứ tự 447 | factor_speed_vector <- 448 | 449 | # Hiển thị kết quả factor_speed_vector 450 | factor_speed_vector 451 | summary(factor_speed_vector) 452 | ``` 453 | 454 | *** =solution 455 | ```{r} 456 | # Tạo speed_vector 457 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 458 | 459 | # Chuyển véc-tơ speed_vector thành véc-tơ có phân biệt thứ tự 460 | factor_speed_vector <- factor(speed_vector, ordered = TRUE, levels = c("slow", "fast", "insane")) 461 | 462 | # Hiển thị kết quả factor_speed_vector 463 | factor_speed_vector 464 | summary(factor_speed_vector) 465 | ``` 466 | 467 | *** =sct 468 | ```{r} 469 | msg = "Không thay đổi các giá trị ảnh hưởng đến biến `speed_vector`." 470 | test_object("speed_vector", undefined_msg = msg, incorrect_msg = msg) 471 | test_function("factor", args = c("x", "ordered", "levels"), 472 | incorrect_msg = c("Tham số đầu tiên cần xác định cho `factor()` là `speed_vector`.", 473 | "Bạn cần chắc chắn rằng đã đặt `ordered = TRUE` bên trong hàm `factor()`.", 474 | "Bạn cần chắc chắn rằng đã đặt `levels = c(\"slow\", \"fast\", \"insane\")` bên trong hàm `factor()`.")) 475 | test_object("factor_speed_vector", eq_condition = "equal", 476 | incorrect_msg = "Có điểm gì đó chưa chính xác với véc-tơ `factor_speed_vector`; kiểm tra lại `speed_vector`, `ordered = TRUE` và `levels = c(\"slow\", \"fast\", \"insane\")` trong giá trị của hàm `factor()`.") 477 | success_msg("Rất tốt! Hãy xem màn hình tương tác console. Bây giờ đã hiển thị thứ tự của véc-tơ với dấu `<`. Tiếp tục làm bài tập tiếp theo nhé!") 478 | ``` 479 | 480 | 481 | --- type:NormalExercise xp:100 skills:1 key:db16e69805625bcfde227743a8cbc985f8482a37 482 | ## So sánh thứ tự của factor 483 | 484 | Sau một ngày làm việc không hiệu quả, 'Chuyên viên phân tích số hai' tiến vào văn phòng làm việc của bạn, bắt đầu phàn nàn rằng 'Chuyên viên số năm' đang làm chậm tiến độ của dự án. Vốn biết rằng chuyên viên số hai có tiếng là láu cá, bạn quyết định kiểm tra thông tin này 485 | 486 | 487 | Véc-tơ `factor_speed_vector` , giờ đã được sắp xếp thứ tự, cho phép chúng ta so sánh các thành phần khác nhau (chuyên viên phân tích dữ liệu trong trường hợp này). 488 | 489 | *** =instructions 490 | - Sử dụng `[2]` để lựa chọn factor từ véc-tơ `factor_speed_vector`, giá trị này được gán cho chuyên viên hai. Lưu giá trị này thành `da2`. 491 | - Sử dụng `[5]` để lựa chọn factor từ véc-tơ `factor_speed_vector`, giá trị này được gán cho chuyên viên hai. Lưu giá trị này thành `da5`. 492 | - Kiểm tra xem `da2` có lớn hơn giá trị `da5` hay không; hiển thị kết quả ra ngoài màn hình. Nhớ rằng bạn có thể sử dụng dấu lớn hơn `>` trong trường hợp này 493 | 494 | *** =hint 495 | - Để lựa chọn giá trị factor của chuyên viên số ba, bạn sẽ cần sử dụng câu lệnh `factor_speed_vector[3]`. 496 | - Để so sánh hai giá trị, bạn có thể sử dụng dấu lớn hơn `>`. Ví dụ: `da3 > da4`. 497 | 498 | *** =pre_exercise_code 499 | ```{r} 500 | # no pec 501 | ``` 502 | 503 | *** =sample_code 504 | ```{r} 505 | # Tạo véc-tơ factor_speed_vector 506 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 507 | factor_speed_vector <- factor(speed_vector, ordered = TRUE, levels = c("slow", "fast", "insane")) 508 | 509 | # Giá trị factor của chuyên viên số 2 510 | da2 <- 511 | 512 | # Giá trị factor của chuyên viên số 5 513 | da5 <- 514 | 515 | # Chuyên viên 2 có làm việc nhanh hơn chuyên viên 5? 516 | 517 | ``` 518 | 519 | *** =solution 520 | ```{r} 521 | # Tạo véc-tơ factor_speed_vector 522 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 523 | factor_speed_vector <- factor(speed_vector, ordered = TRUE, levels = c("slow", "fast", "insane")) 524 | 525 | # Giá trị factor của chuyên viên số 2 526 | da2 <- factor_speed_vector[2] 527 | 528 | # Giá trị factor của chuyên viên số 5 529 | da5 <- factor_speed_vector[5] 530 | 531 | # Chuyên viên 2 có làm việc nhanh hơn chuyên viên 5? 532 | da2 > da5 533 | ``` 534 | 535 | *** =sct 536 | ```{r} 537 | msg = "Đừng thay đổi giá trị của véc-tơ `speed_vector` và `factor_speed_vector`!" 538 | test_object("speed_vector", undefined_msg = msg, incorrect_msg = msg) 539 | test_object("factor_speed_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 540 | 541 | msg <- "Bạn đã lấy đúng giá trị của %s chuyên viên chưa? Bạn có thể sử dụng hàm `factor_speed_vector[%s]`." 542 | test_object("da2", eq_condition = "equal", incorrect_msg = sprintf(msg, "second", "2")) 543 | test_object("da5", eq_condition = "equal", incorrect_msg = sprintf(msg, "fifth", "5")) 544 | test_output_contains("da2 > da5", incorrect_msg = "Bạn đã so sánh đúng giá trị của `da2` và `da5` chưa? Bạn có thể sử dụng dấu lớn hơn `>`. Hiển thị kết quả ngoài màn hình") 545 | 546 | success_msg("Tuyệt vời! Kết quả trên cho bạn thấy điều gì? Chuyên viên hai phàn nàn về chuyên viên năm trong khi chính chuyên viên số hai mới là người làm chậm tiến độ của dự án! Kết quả này kết thúc chương về factor. Với kiến thức nền tảng vững vàng về véc-tơ, ma trận và factor, bạn đã sẵn sàng để tìm hiểu bảng dữ liệu data frame, một cấu trúc dữ liệu vô cùng quan trọng trong R.") 547 | ``` 548 | 549 | 550 | 551 | -------------------------------------------------------------------------------- /chapter5.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : Chương 5 3 | title : Data frames 4 | description : Phần lớn dữ liệu sử dụng để phân tích được lưu dưới dạng data frame. Đến cuối chương này, bạn sẽ có thể tạo được data frame, lựa chọn data frame và sắp xếp thứ tự của data frame theo biến xác định. 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:7f95849020a2563168920409022ce7bed20835b5 7 | ## Data frame là gì? 8 | 9 | Trong bài giảng từ các phần trước, bạn hẳn còn nhớ rằng tất cả các thành phần trong một ma trận phải có cùng một định dạng. Ở phần trước, tập dữ liệu Star Wars bạn có chỉ chứa duy nhất định dạng kiểu số. 10 | 11 | Tuy nhiên, khi tiến hành khảo sát thị trường, ta thường hay phải sử dụng những câu hỏi như sau: 12 | 13 | - 'Bạn đã kết hôn chưa?' hoặc câu hỏi dạng 'có/không' (`logical`) 14 | - 'Bạn bao nhiêu tuổi?' (`numeric`) 15 | - 'Bạn đánh giá gì về sản phẩm này?' hoặc các câu hỏi mở khác (`character`) 16 | - ... 17 | 18 | Kết quả khảo sát từ những câu hỏi trong bảng nghiên cứu thị trường ở trên là một tập dữ liệu với các định dạng dữ liệu khác nhau. Bạn sẽ thấy rằng, khi phân tích dữ liệu, chúng ta sẽ phải xử lý dữ liệu với nhiều định dạng khác nhau. 19 | 20 | Data frame là một tập dữ liệu, trong đó mỗi cột là một biến, mỗi dòng là một quan sát. Định dạng dữ liệu này khá tương đồng với các phần mềm phân tích thống kê khác như SAS hoặc SPSS 21 | 22 | *** =instructions 23 | Ấn 'Submit Answer'. Tập dữ liệu [`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars) sẽ được hiển thị ra ngoài màn hình tương tác. 24 | 25 | *** =hint 26 | Ấn 'Submit Answer' và xem kết quả 27 | 28 | *** =pre_exercise_code 29 | ```{r} 30 | # no pec 31 | ``` 32 | 33 | *** =sample_code 34 | ```{r} 35 | # Hiển thị tập dữ liệu đính kèm trong R 36 | mtcars 37 | ``` 38 | 39 | *** =solution 40 | ```{r} 41 | # Hiển thị tập dữ liệu đính kèm trong R 42 | mtcars 43 | ``` 44 | 45 | *** =sct 46 | ```{r} 47 | test_output_contains("mtcars", incorrect_msg = "Không thay đỗi các câu lệnh. Chắc chắn rằng bạn đã gõ chính xác `mtcars`.") 48 | success_msg("Tuyệt vời! Tiếp tục làm bài tập tiếp theo nhé.") 49 | ``` 50 | 51 | 52 | --- type:NormalExercise xp:100 skills:1 key:3d0e64ecf5f69521ee538ecc713caa02b8b0ec46 53 | ## Kiểm tra dữ liệu 54 | 55 | Thật là nhiều ô-tô! 56 | 57 | Khi phân tích dữ liệu, xử lý các tập dữ liệu lớn không phải là điều hiếm thấy. Khi bạn xử lý các tập dữ liệu lớn (hoặc cực lớn), đối với các nhà phân tích dữ liệu, việc đầu tiên là cần phải hiểu chính xác cấu trúc và các thành phần chính trong dữ liệu. Do đó, hiển thị một phần của tập dữ liệu cần phân tích sẽ rất hữu ích trong trường hợp này. 58 | 59 | Vậy thì làm thế nào để thực hiện trên R? Thế này nhé, hàm 60 | [`head()`](http://www.rdocumentation.org/packages/utils/functions/head) 61 | cho phép bạn xem các quan sát đầu tiên trong tập dữ liệu. Tương tự, hàm [`tail()`](http://www.rdocumentation.org/packages/utils/functions/head) cho phép bạn hiển thị các quan sát cuối cùng trong tập dữ liệu. 62 | 63 | Cả hai hàm [`head()`](http://www.rdocumentation.org/packages/utils/functions/head) và [`tail()`](http://www.rdocumentation.org/packages/utils/functions/head) đều hiển thị 'header' của tập dữ liệu, cho phép bạn nắm được thông tin về tên các biến trong tập dữ liệu cần phân tích. 64 | 65 | *** =instructions 66 | Gọi hàm [`head()`](http://www.rdocumentation.org/packages/utils/functions/head) từ tập dữ liệu [`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars) để xem tên biến và các quan sát đầu tiên của dữ liệu. 67 | 68 | *** =hint 69 | `head(mtcars)` sẽ hiển thị các quan sát đầu tiên của tập dữ liệu `mtcars`. 70 | 71 | *** =pre_exercise_code 72 | ```{r} 73 | # no pec 74 | ``` 75 | 76 | *** =sample_code 77 | ```{r} 78 | # Gọi hàm head() trong tập mtcars 79 | 80 | ``` 81 | 82 | *** =solution 83 | ```{r} 84 | # Gọi hàm head() trong tập mtcars 85 | head(mtcars) 86 | ``` 87 | 88 | *** =sct 89 | ```{r} 90 | test_function("head", "x", incorrect_msg = "Bạn đã gõ đúng tên tập dữ liệu `mtcars` trong hàm `head()` hay chưa?") 91 | test_output_contains("head(mtcars)", incorrect_msg = "Bạn chỉ cần hiển thị kết quả của hàm `head()`, không cần phải gán kết quả cho giá trị mới.") 92 | success_msg("Tuyệt vời! Chúng ta có gì trong tập dữ liệu này đây? Ví dụ, `hp` cho chúng ta thông tin về mã lực của các loại xe; xe Datsun có mã lực thấp nhất trong 6 chiếc xe được hiển thị. Để biết được tổng quan ý nghĩa của các biến, gõ lệnh `?mtcars` trong màn hình tương tác và xem tài liệu mô tả. Làm bài tập tiếp theo nhé!"); 93 | ``` 94 | 95 | --- type:NormalExercise xp:100 skills:1 key:f4d5b1a2c4aef31645fc7e3505e699fb6e48f3e6 96 | ## Xem cấu trúc dữ liệu 97 | 98 | Một phương pháp khác để theo dõi khái quát cấu trúc của dữ liệu là câu lệnh [`str()`](http://www.rdocumentation.org/packages/utils/functions/str). Hàm [`str()`](http://www.rdocumentation.org/packages/utils/functions/str) hiển thị cấu trúc dữ liệu trong tập dữ liệu cần phân tích. Đối với tập dữ liệu mtcars, hàm này cho ta biết một số thông tin sau: 99 | 100 | - Tổng số quan sát (32 loại xe hơi) 101 | - Tổng số các biến (11 thuộc tính của xe hơi) 102 | - Danh sách tất cả các biến (VD. `mpg`, `cyl` ... ) 103 | - Kiểu dữ liệu (VD: `num`) 104 | - Một số quan sát đầu tiên 105 | 106 | Sử dụng câu lệnh [`str()`](http://www.rdocumentation.org/packages/utils/functions/str) có lẽ sẽ là bước đầu tiên bạn cần thực hiện khi bạn bắt đàu phân tích một tập dữ liệu mới. Đây là cách rất tốt để bạn hiểu thêm về cấu trúc dữ liệu trước khi đi vào phân tích dữ liệu chi tiết. 107 | 108 | *** =instructions 109 | Xem xét cấu trúc dữ liệu của tập dữ liệu [`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars). Lưu ý hãy kiểm tra xem bạn có nhận được kết quả như bài tập ở phần trước hay không. 110 | 111 | *** =hint 112 | Sử dụng hàm [`str()`](http://www.rdocumentation.org/packages/utils/functions/str) vào tập dữ liệu [`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars). 113 | 114 | *** =pre_exercise_code 115 | ```{r} 116 | # no pec 117 | ``` 118 | 119 | *** =sample_code 120 | ```{r} 121 | # Tìm hiểu cấu trúc dữ liệu của tập mtcars 122 | ``` 123 | 124 | *** =solution 125 | ```{r} 126 | # Tìm hiểu cấu trúc dữ liệu của tập mtcars 127 | str(mtcars) 128 | ``` 129 | 130 | *** =sct 131 | ```{r} 132 | test_output_contains("str(mtcars)", incorrect_msg = "Bạn đã sử dụng đúng lệnh `str()` với tập `mtcars`?") 133 | success_msg("Rất tốt! Bạn có thấy tất cả các thông tin hiển thị như bài tập của chúng ta hay không? Làm bài tập tiếp theo nhé.") 134 | ``` 135 | 136 | 137 | --- type:NormalExercise xp:100 skills:1 key:df0b89706d90526b3c0bbe15e400b74cbd900704 138 | ## Tạo data frame 139 | 140 | Chỉ sử dụng tập dữ liệu có sẵn trong R là chưa đủ, phần tiếp theo của chương này sẽ hướng dẫn các bạn cách thức tự tạo tập dữ liệu. 141 | 142 | Ví dụ, bạn muốn tạo một data frame mô tả các thuộc tính của 8 hành tinh trong hệ mặt trời. Theo gợi ý từ bạn của bạn, các đặc tính cơ bản gồm có: 143 | 144 | - Loại hành tinh (Terrestrial hay Gas Giant). 145 | - Bán kính (so với trái đất) 146 | - Tần suất quay xung quanh mặt trời (so với trái đất) 147 | - Hành tinh có lớp vành đai hay không (TRUE hoặc FALSE). 148 | 149 | Sau khi nghiên cứu thông tin từ [Wikipedia](http://en.wikipedia.org/wiki/Planet), giờ bạn đã cảm thấy tự tin để tạo các véc-tơ: `name`, `type`, `diameter`, `rotation` and `rings`. Các thành phần đầu tiên của mỗi véc-tơ tương ứng với các quan sát đầu tiên trong tập dữ liệu. 150 | 151 | Bạn có thể tự tạo data frame với hàm [`data.frame()`](http://www.rdocumentation.org/packages/base/functions/data.frame). Sau khi tạo các véc-tơ, bạn có thể đưa các véc-tơ đó vào data frame. Bởi vì mỗi cột có độ dài như nhau, nên các véc-tơ bạn đưa vào cũng cần có độ dài như nhau. Tuy nhiên, đừng quên rằng data frame có thể chứa những kiểu dữ liệu khác nhau 152 | 153 | *** =instructions 154 | Sử dụng hàm [`data.frame()`](http://www.rdocumentation.org/packages/base/functions/data.frame) để tạo data frame. Sử dụng các véc-tơ `name`, `type`, `diameter`, `rotation` và `rings` theo thứ tự, các véc-tơ này là tham số trong `data.frame()`. Gọi kết quả từ data frame `planets_df`. 155 | 156 | *** =hint 157 | Hàm `data.frame()` có thể xây dựng như sau: 158 | 159 | ``` 160 | data.frame(planets, type, diameter) 161 | ``` 162 | Bạn có thể hoàn thành nó không? 163 | 164 | *** =pre_exercise_code 165 | ```{r} 166 | # no pec 167 | ``` 168 | 169 | *** =sample_code 170 | ```{r} 171 | # Xây dựng các véc-tơ 172 | name <- c("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune") 173 | type <- c("Terrestrial planet", "Terrestrial planet", "Terrestrial planet", 174 | "Terrestrial planet", "Gas giant", "Gas giant", "Gas giant", "Gas giant") 175 | diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883) 176 | rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67) 177 | rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE) 178 | 179 | # Tạo data frame 180 | planets_df <- 181 | 182 | ``` 183 | 184 | *** =solution 185 | ```{r} 186 | # Xây dựng các véc-tơ 187 | name <- c("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune") 188 | type <- c("Terrestrial planet", "Terrestrial planet", "Terrestrial planet", 189 | "Terrestrial planet", "Gas giant", "Gas giant", "Gas giant", "Gas giant") 190 | diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883) 191 | rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67) 192 | rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE) 193 | 194 | # Tạo data frame 195 | planets_df <- data.frame(name, type, diameter, rotation, rings) 196 | ``` 197 | 198 | *** =sct 199 | ```{r} 200 | msg = "Không thay đổi các tham số khi xây dựng véc-tơ. Chỉ cần gọi hàm `data.frame()` để tạo data frame `planets_df`." 201 | test_object("name", undefined_msg = msg, incorrect_msg = msg) 202 | test_object("type", undefined_msg = msg, incorrect_msg = msg) 203 | test_object("diameter", undefined_msg = msg, incorrect_msg = msg) 204 | test_object("rotation", undefined_msg = msg, incorrect_msg = msg) 205 | test_object("rings", undefined_msg = msg, incorrect_msg = msg) 206 | 207 | test_object("planets_df", 208 | incorrect_msg = "Bạn đã sử dụng hàm `data.frame()` chính xác chưa? Lưu ý thứ tự các véc-tơ trong `data.frame()`, các véc-tơ cần được sắp xếp theo thứ tự: `name`, `type`, `diameter`, `rotation` and finally `rings`.") 209 | 210 | success_msg("Rất tốt! Làm bài tập tiếp theo nhé. Theo logic tự nhiên, công việc tiếp theo của bạn sẽ là phân tích tập dữ liệu bạn vừa xây dựng."); 211 | ``` 212 | 213 | 214 | --- type:NormalExercise xp:100 skills:1 key:c13ea421dd078030a225f49e53a8927ce8fefbe0 215 | ## Tạo data frame (2) 216 | 217 | Data frame `planets_df` sẽ có 8 quan sát với 5 biến. Tập dữ liệu này đã được lưu, bạn có thể trực tiếp sử dụng tập dữ liệu này. 218 | 219 | *** =instructions 220 | Sử dụng hàm [`str()`](http://www.rdocumentation.org/packages/utils/functions/str) để khám phá cấu trúc các biến trong tập dữ liệu `planets_df`. 221 | 222 | *** =hint 223 | `planets_df` đã sẵn sàng cho bạn phân tích, thế nên hàm `str(planets_df)` sẽ cho phép thực hiện bài tập trên. 224 | 225 | *** =pre_exercise_code 226 | ```{r} 227 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 228 | ``` 229 | 230 | *** =sample_code 231 | ```{r} 232 | # Kiểm tra cấu trúc planets_df 233 | ``` 234 | 235 | *** =solution 236 | ```{r} 237 | # Kiểm tra cấu trúc planets_df 238 | str(planets_df) 239 | ``` 240 | 241 | *** =sct 242 | ```{r} 243 | msg = "Không xóa hay ghi đè lên tập dữ liệu `planets_df`" 244 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 245 | test_output_contains("str(planets_df)", incorrect_msg = "Bạn đã có kết quả của cấu trúc từ tập dữ liệu `planets_df`? Sử dụng hàm `str()` để hoàn thành!") 246 | success_msg("Tuyệt vời! Giờ thì bạn đã hiểu rất rõ ràng cấu trúc của tập `planets_df`. Đến lúc bạn cần biết làm thế nào để lựa chọn các giá trị trong tập dữ liệu này. Ta sẽ học tất cả những điều này trong các bài tập tiếp theo!") 247 | ``` 248 | 249 | 250 | --- type:NormalExercise xp:100 skills:1 key:8c664726b8a173cda730cbb20a52ac1795d9a0e9 251 | ## Lựa chọn các giá trị trong data frame 252 | 253 | Tương tự như véc-tơ và ma-trận, bạn có thể lựa chọn các giá trị trong data frame với dấu ngoặc vuông `[ ]`. Băng cách sử dụng dấu phẩy, bạn có thể lựa chọn dòng hoặc côt theo thứ tự. Ví dụ: 254 | 255 | - `my_df[1,2]` lựa chọn giá trị của dòng 1 cột 2 trong `my_df`. 256 | - `my_df[1:3,2:4]` lựa chọn dòng 1,2,3 và các dòng 2,3,4 trong `my_df`. 257 | 258 | Đôi lúc, bạn lại muốn lựa chọn tất cả các giá trị của hàng hoặc cột. Ví dụ 259 | `my_df[1, ]` sẽ lựa chọn tất cả các giá trị của dòng thứ nhất. Giờ ta hãy áp dụng bài tập trên vào tập dữ liệu `planets_df`! 260 | 261 | *** =instructions 262 | - Từ tập dữ liệu `planets_df`, lựa chọn bán kính của Mercury (sao Thủy): đây là giá trị của dòng một, cột ba. 263 | - Từ tập dữ liệu `planets_df`, lựa chọn tất cả dữ liệu của Mars (sao Hỏa) tại dòng số 4 264 | 265 | *** =hint 266 | Để lựa chọn bán kính của Venus (sao Kim - dòng số hai), bạn sẽ cần sử dụng câu lệnh `planets_df[2,3]`. 267 | 268 | *** =pre_exercise_code 269 | ```{r} 270 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 271 | ``` 272 | 273 | *** =sample_code 274 | ```{r} 275 | # Data frame planets_df từ bài tập phần trước sẽ được load 276 | 277 | # Hiển thị kết quả bán kính của Mercury (dòng 1, cột 3) 278 | 279 | # Hiển thị toàn bộ dữ liệu của Mars (dòng số 4) 280 | 281 | ``` 282 | 283 | *** =solution 284 | ```{r} 285 | # Data frame planets_df từ bài tập phần trước sẽ được load 286 | 287 | # Hiển thị kết quả bán kính của Mercury (dòng 1, cột 3) 288 | planets_df[1,3] 289 | 290 | # Hiển thị toàn bộ dữ liệu của Mars (dòng số 4) 291 | planets_df[4, ] 292 | ``` 293 | 294 | *** =sct 295 | ```{r} 296 | msg = "Không xóa hoặc thay đổi dữ liệu `planets_df`!" 297 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 298 | test_output_contains("planets_df[1,3]", incorrect_msg = "Bạn đã lựa chọn và hiển thị bán kính của Mercury (sao Thủy) chưa? Bạn có thể sử dụng `[1,3]`.") 299 | test_output_contains("planets_df[4, ]", incorrect_msg = "Bạn đã lựa chọn và hiển thị tất cả dữ liệu của Mars (sao Hỏa) chưa? Bạn có thể sử dụng `[4,]`.") 300 | success_msg("Tuyệt vời! Bện cạnh việc việc lựa chọn các biến theo thứ tự chữ số, bạn có thể sử dụng tên các biến trong data frame. Ta sẽ học kỹ thuật này trong bài tập tiếp theo.") 301 | ``` 302 | 303 | 304 | --- type:NormalExercise xp:100 skills:1 key:faf104fb0c605fd89f048648a4a588200bc89c76 305 | ## Lựa chọn các giá trị trong data frame (2) 306 | 307 | Bên cạnh việc sử dụng các chữ số để lựa chọn các thành phần trong data frame, bạn có thể sử dụng tên các biến để lựa chọn các cột. 308 | 309 | Giả sử bạn một lựa chọn ba giá trị đầu tiên của cột `type`, bạn có thể sử dụng cách sau: 310 | 311 | ``` 312 | planets_df[1:3,1] 313 | ``` 314 | 315 | Điểm yếu của phương pháp này là bạn phải biết chính xác thứ tự của cột `type`. Phương pháp này sẽ rất khó thực hiện khi dữ liệu của bạn có rất nhiều biến. Do đó, lựa chọn theo tên của biến sẽ đơn giản hơn rất nhiều: 316 | 317 | ``` 318 | planets_df[1:3,"type"] 319 | ``` 320 | 321 | *** =instructions 322 | Lựa chọn và hiển thị 5 giá trị đầu tiên của biến `"diameter"` trong `planets_df`. 323 | 324 | *** =hint 325 | Bạn có thể lựa chọn 5 giá trị đầu tiên với hàm `planets_df[1:5, ...]`. Bạn có thể điền tiếp vào dấu `...` để chỉ lựa chọn biến `"diameter"` không? 326 | 327 | 328 | *** =pre_exercise_code 329 | ```{r} 330 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 331 | ``` 332 | 333 | *** =sample_code 334 | ```{r} 335 | # Data frame planets_df từ bài tập phần trước sẽ được load 336 | 337 | # Lựa chọn 5 giá trị đầu tiên của cột diameter 338 | 339 | ``` 340 | 341 | *** =solution 342 | ```{r} 343 | # Data frame planets_df từ bài tập phần trước sẽ được load 344 | 345 | # Lựa chọn 5 giá trị đầu tiên của cột diameter 346 | planets_df[1:5, "diameter"] 347 | ``` 348 | 349 | *** =sct 350 | ```{r} 351 | msg = "Không xóa hoặc thay đổi dữ liệu `planets_df`!" 352 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 353 | test_output_contains("planets_df[1:5, \"diameter\"]", incorrect_msg = "Bạn đã lựa chọn chính xác 5 giá trị đầu tiên của diameter chưa? Bạn có thể sử dụng `[1:5, \"diameter\"]`") 354 | success_msg("Rất tốt! Làm bài tập tiếp theo nhé!") 355 | ``` 356 | 357 | 358 | --- type:NormalExercise xp:100 skills:1 key:e550ecb6ec45b856e6160ddfbb3d7875998e8365 359 | ## Chỉ lựa chọn các hành tinh có vành đai 360 | 361 | Bạn sẽ thường hay lựa chọn tất cả các cột, hay nói một cách khác - tất cả các biến trong data frame. Chẳng hạn, nếu bạn muốn lựa chọn tất cả các giá trị của biến `diameter`, cả hai cách sau đều có thể thực hiện được: 362 | 363 | ``` 364 | planets_df[,3] 365 | planets_df[,"diameter"] 366 | ``` 367 | 368 | Tuy nhiên, có một cách nhanh hơn. Bạn có thể sử dụng ký tự `$`: 369 | 370 | ``` 371 | planets_df$diameter 372 | ``` 373 | 374 | *** =instructions 375 | - Sử dụng ký tự `$` để lựa chọn biến `rings` từ tập dữ liệu `planets_df`. Lưu kết quả vào véc-tơ `rings_vector`. 376 | - Hiển thị `rings_vector` để chắc chắn bạn đã làm đúng. 377 | 378 | *** =hint 379 | `planets_df$diameter` cho phép lựa chọn biên `diameter` từ tập dữ liệu `planets_df`; bạn sẽ cần làm gì để lựa chọn biến `rings` đây? 380 | 381 | *** =pre_exercise_code 382 | ```{r} 383 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 384 | ``` 385 | 386 | *** =sample_code 387 | ```{r} 388 | # Data frame planets_df từ bài tập phần trước sẽ được load 389 | 390 | # Lựa chọn biến rings từ dữ liệu planets_df 391 | rings_vector <- 392 | 393 | # Hiển thị kết quả rings_vector 394 | ``` 395 | 396 | *** =solution 397 | ```{r} 398 | # Data frame planets_df từ bài tập phần trước sẽ được load 399 | 400 | # Lựa chọn biến rings từ dữ liệu planets_df 401 | rings_vector <- planets_df$rings 402 | 403 | # Hiển thị kết quả rings_vector 404 | rings_vector 405 | ``` 406 | 407 | *** =sct 408 | ```{r} 409 | msg = "Không xóa hoặc thay đổi dữ liệu `planets_df`!" 410 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 411 | test_object("rings_vector", 412 | incorrect_msg = "Bạn đã lựa chọn biến `rings` từ tập dữ liệu `planets_df` chính xác chưa? Sử dụng hàm `$rings`. Lưu kết quả vào véc-tơ `rings_vector`.") 413 | test_output_contains("rings_vector", incorrect_msg = "Đừng quên hiển thị kết quả của véc-tơ `rings_vector`sau khi khởi tạo!") 414 | success_msg("Tuyệt vời! Giờ thì cùng khám phá cách khác để lấy dữ liệu trong bài tập tiếp theo nhé!") 415 | ``` 416 | 417 | 418 | --- type:NormalExercise xp:100 skills:1 key:1581bf4667477f274188f4f637ec7fdc73659651 419 | ## Chỉ lựa chọn các hành tinh có vành đai (2) 420 | 421 | Bạn có lẽ vẫn còn nhớ từ hồi còn học phổ thông rằng, một số hành tinh có vành đai, một số khác thì không. Tuy nhiên, mớ kiến thức này cũng từ khá lâu rồi nên bạn không thể nhớ được tên các hành tinh loại này. 422 | 423 | R có thể giúp bạn như thế nào đây? 424 | 425 | Nếu bạn sử dụng `rings_vector` trong màn hình tương tác, bạn sẽ nhận được kết quả: 426 | 427 | ``` 428 | [1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE 429 | ``` 430 | Điều này có nghĩa rằng 4 quan sát đầu tiên (4 hành tinh đầu tiên) không có vành đai (`FALSE`), nhưng các hành tinh khác thì có (`TRUE`). Tuy nhiên, bạn không thể có một cái nhìn khái quát của tên các hành tinh, bán kính, v.v. Hãy sử dụng `rings_vector` để lựa chọn dữ liệu từ 4 hành tinh có vành đai. 431 | 432 | *** =instructions 433 | Các câu lệnh bên cho phép lựa chọn cột `name` của tất cả các hành tinh có vành đai. Áp dụng câu lệnh này, sao cho thay vì chỉ lựa chon cột `name`, lựa chọn tất cả các cột với các hành tinh có vành đai. 434 | 435 | *** =hint 436 | Nhớ rằng để lựa chọn _tất cả_ các cột, bạn có thể đơn giản là để trống phần bên phải sau dấu phẩy! Nghĩa là bạn có thể sử dụng `[rings_vector, ]`. 437 | 438 | *** =pre_exercise_code 439 | ```{r} 440 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 441 | rings_vector <- planets_df$rings 442 | ``` 443 | 444 | *** =sample_code 445 | ```{r} 446 | # Data frame planets_df từ bài tập phần trước sẽ được load 447 | 448 | #Áp dụng đoạn code trên với tất cả các cột với các hành tinh có vành đai 449 | planets_df[rings_vector, "name"] 450 | ``` 451 | 452 | *** =solution 453 | ```{r} 454 | # Data frame planets_df từ bài tập phần trước sẽ được load 455 | 456 | #Áp dụng đoạn code trên với tất cả các cột với các hành tinh có vành đai 457 | planets_df[rings_vector, ] 458 | ``` 459 | 460 | *** =sct 461 | ```{r} 462 | msg <- "Không xóa hoặc thay đổi dữ liệu `planets_df`!" 463 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 464 | test_object("rings_vector", undefined_msg = msg, incorrect_msg = msg) 465 | test_output_contains('planets_df[rings_vector, ]', incorrect_msg = "Bạn đã sử dụng câu lệnh chính xác chưa? Bạn có thể sử dụng `planets_df[rings_vector, ]`. Lưu ý sử dụng dấu phẩy trong trường hợp này!") 466 | success_msg("Tuyệt vời! Trong bài tập tiếp theo, chúng ta sẽ học một phương pháp khác, hiệu quả hơn.") 467 | ``` 468 | 469 | 470 | --- type:NormalExercise xp:100 skills:1 key:a4a8b72a74097196eb2f8a28b056987aae834565 471 | ## Chỉ lựa chọn các hành tinh có vành đai - cách ngắn gọn 472 | 473 | Chính xác thì bạn đã học được gì trong các bài tập ở phần trước? Bạn lựa chọn các tập dữ liệu con từ data frame (`planets_df`) dựa theo điều kiện cho trước (có vành đai hay không có vành đai). 474 | 475 | Giờ thì chúng ta sẽ lên một cấp độ cao hơn và sử dụng hàm 476 | [`subset()`](http://www.rdocumentation.org/packages/base/functions/subset). Bạn có thể sử dụng hàm [`subset()`](http://www.rdocumentation.org/packages/base/functions/subset), hàm này cho phép bạn thực hiện nhanh hơn những câu lệnh mà bạn đã sử dụng trong phần trước. 477 | 478 | ``` 479 | subset(my_df, subset = some_condition) 480 | ``` 481 | 482 | Tham số đầu tiên của [`subset()`](http://www.rdocumentation.org/packages/base/functions/subset) xác định tập dữ liệu bạn muốn sử dụng. Bằng cách thêm tham số thứ hai, bạn cung cấp cho R các thông tin và điều kiện cần thiết để lọc dữ liệu. 483 | 484 | Các câu lệnh dưới đây sẽ cho bạn kết quả chính xác như bài tập ở phần trước. Tuy nhiên ở phần này, bạn không cần phải sử dụng véc-tơ `rings_vector`! 485 | 486 | 487 | ``` 488 | subset(planets_df, subset = rings) 489 | ``` 490 | 491 | *** =instructions 492 | Sử dụng hàm `subset()` với `planets_df` để lựa chọn các hành tinh có bán kính nhỏ hơn trái đất. Bởi vì biến `diameter` là biến tương đối, nên điều kiện cần thiết sẽ là `diameter < 1`. 493 | 494 | 495 | 496 | *** =hint 497 | `subset(planets_df, subset = ...)` gần như hoàn thiện rồi; bạn có thể điền nốt vào dâu `...` không? 498 | 499 | *** =pre_exercise_code 500 | ```{r} 501 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 502 | ``` 503 | 504 | *** =sample_code 505 | ```{r} 506 | # Data frame planets_df từ bài tập phần trước sẽ được load 507 | 508 | # Lựa chọn điều kiện diameter < 1 509 | 510 | ``` 511 | 512 | *** =solution 513 | ```{r} 514 | # Data frame planets_df từ bài tập phần trước sẽ được load 515 | 516 | # Lựa chọn điều kiện diameter < 1 517 | subset(planets_df, subset = diameter < 1) 518 | ``` 519 | 520 | *** =sct 521 | ```{r} 522 | msg = "Không xóa hoặc thay đổi dữ liệu `planets_df`!" 523 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 524 | test_correct({ 525 | test_output_contains("subset(planets_df, subset = diameter < 1)", incorrect_msg = "Bạn đã sử dụng điều kiện `subset = ...` chính xác chưa. Điều kiện cần thiết là `diameter < 1`. Hiển thị kết quả.") 526 | }, { 527 | test_function("subset", args = "x", 528 | not_called_msg = "Hãy chắc chắn rằng bạn đã sử dụng hàm `subset()`!", 529 | incorrect_msg = "Tham số đầu tiên trong hàm `subset()` là `planets_df`.") 530 | }) 531 | success_msg("Tuyệt vời! Hàm `subset()` không chỉ đơn giản hơn, mà còn dễ hiểu hơn khi theo dõi các đoạn code của bạn. Làm bài tập tiếp theo nhé.") 532 | ``` 533 | 534 | 535 | --- type:NormalExercise xp:100 skills:1 key:6a6fe74d3917c37380f7ac616ce084aa7814fb8a 536 | ## Sắp xếp thứ tự dữ liệu 537 | 538 | Sắp xếp thứ tự trong biến là một trong những công việc rất hay được sử dụng. Khi phân tích dữ liệu, bạn có thể sắp xếp thứ tự theo một biến nhất định trong tập dữ liệu. Với R, bạn có thể sử dụng hàm [`order()`](http://www.rdocumentation.org/packages/base/functions/order). 539 | 540 | [`order()`](http://www.rdocumentation.org/packages/base/functions/order) là hàm cho phép bạn sắp xếp thứ tự của mỗi giá trị trong véc-tơ hoặc biến, ví dụ: 541 | 542 | ``` 543 | > a <- c(100, 10, 1000) 544 | > order(a) 545 | [1] 2 1 3 546 | ``` 547 | 10, đây là giá trị ở vị trí thứ 2 của `a`, đây là giá trị nhỏ nhất trong véc-tơ a. Do đó, kết quả trả ra 2 ở vị trí đầu tiên là giá trị nhỏ nhất, 1 sẽ là giá trị thứ 2 (100 là giá trị lớn thứ 2) trong hàm `order(a)`. 548 | 549 | Điều này có nghĩa là chúng ta có thể sử dụng kết quả của `order(a)` để thay đổi thứ tự các giá trị trong `a` 550 | 551 | ``` 552 | > a[order(a)] 553 | [1] 10 100 1000 554 | ``` 555 | 556 | *** =instructions 557 | Thực hiện thử với hàm [`order()`](http://www.rdocumentation.org/packages/base/functions/order) trong màn hình giao diện. Click vào nút 'Submit Answer' khi bạn sẵn sàng để tiếp tục 558 | 559 | *** =hint 560 | Chỉ cần gõ lệnh [`order()`](http://www.rdocumentation.org/packages/base/functions/order) trong màn hình tương tác! 561 | 562 | *** =pre_exercise_code 563 | ```{r} 564 | # no pec 565 | ``` 566 | 567 | *** =sample_code 568 | ```{r} 569 | # Sử dụng hàm order với màn hình tương tác 570 | ``` 571 | 572 | *** =solution 573 | ```{r} 574 | # Sử dụng hàm order với màn hình tương tác 575 | ``` 576 | 577 | *** =sct 578 | ```{r} 579 | success_msg("Tuyệt vời! Giờ thì ta hãy sử dụng hàm `order()` để sắp xếp thứ tự trong data frame!") 580 | ``` 581 | 582 | 583 | --- type:NormalExercise xp:100 skills:1 key:fa88b58bf2cf62e0c181dfdcbdd2e1ddeac66807 584 | ## Sắp xếp thứ tự trong data frame 585 | 586 | Giờ bạn đã nắm được cách sử dụng hàm [`order()`](http://www.rdocumentation.org/packages/base/functions/order). Giờ hãy thực hiện vài bài tập hữu ích với hàm trên. Giả sử bạn muốn sắp xếp thứ tự data frame của bạn, sao cho các hành tinh nhỏ nhất đứng trước, các hành tinh lớn hơn sẽ đứng sau. Ta cần sắp xếp biến `diameter`. 587 | 588 | *** =instructions 589 | - Gọi hàm `order()` đối với `planets_df$diameter` (cột `diameter` của tập dữ liệu `planets_df`). Lưu kết quả với véc-tơ `positions`. 590 | - Giờ thay đổi thứ tự `planets_df` với véc-tơ `positions` với vị trí của dòng trong ngoặc vuông. Giữ tất cả các cột 591 | 592 | *** =hint 593 | - Sử dụng `order(planets_df$diameter)` để tạo véc-tơ `positions`. 594 | - Giờ thị, bạn có thể sử dụng `positions` bên trong dấu ngoặc vuông: `planets_df[...]`; bạn có thể điền nốt phần còn lại `...` không? 595 | 596 | *** =pre_exercise_code 597 | ```{r} 598 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 599 | ``` 600 | 601 | *** =sample_code 602 | ```{r} 603 | # Data frame planets_df từ bài tập phần trước sẽ được load 604 | 605 | # Sử dụng order() để tạo véc-tơ chứa thứ tự các giá trị positions 606 | positions <- 607 | 608 | # Sử dụng positions để sắp xêp planets_df 609 | 610 | ``` 611 | 612 | *** =solution 613 | ```{r} 614 | # Data frame planets_df từ bài tập phần trước sẽ được load 615 | 616 | # Sử dụng order() để tạo véc-tơ chứa thứ tự các giá trị positions 617 | positions <- order(planets_df$diameter) 618 | 619 | # Sử dụng positions để sắp xêp planets_df 620 | planets_df[positions, ] 621 | ``` 622 | 623 | *** =sct 624 | ```{r} 625 | msg = "Không xóa hoặc thay đổi dữ liệu `planets_df`!" 626 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 627 | test_object("positions", 628 | incorrect_msg = "Bạn đã tính chính xác biến `positions` hay chưa? Bạn có thể sử dụng `sort(planets_df$diameter)`.") 629 | test_output_contains("planets_df[positions,]", 630 | incorrect_msg = "Sử dụng hàm `planets_df[positions, ]` để sắp xếp lại thứ tự `planets_df`; lưu ý sử dụng dấu phẩy trong ngoặc vuông!") 631 | success_msg("Tuyệt vời! Bài tập này kết thúc chương nói về data frame. Nhớ rằng với R data frame là kiểu dữ liệu rất quan trong bởi lẽ bạn sẽ phải sử dụng data frame trong suốt quá trình phân tích dữ liệu. Một kiểu cấu trúc dữ liệu thường gặp khác là list, và chúng ta sẽ cùng tìm hiểu thêm về list trong chương tiếp theo.") 632 | ``` 633 | 634 | 635 | -------------------------------------------------------------------------------- /chapter3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : Chương 3 3 | title : Ma trận 4 | description : Trong chương này, bạn sẽ được học cách sử dụng ma trận trong R. Sau khi học xong, bạn sẽ thành thạo trong việc thiết lập ma trận và biết cách thực hiện những tính toán cơ bản trong ma trận. Để minh họa cho những điều trên, bạn sẽ phân tích doanh thu bán vé của Star Wars. Chúc bạn may mắn! 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:d61aeba84c 7 | ## Thế nào là ma trận? 8 | 9 | Trong ngôn ngữ của R, ma trận là một tập hợp các yếu tố thuộc cùng một loại dữ liệu (số, ký tự hoặc lôgic) được sắp xếp thành dòng và cột với số lượng cố định. Ma trận chỉ có hai chiều là chiều dòng và cột. 10 | 11 | Bạn có thể xây dựng một ma trận trong R với hàm [`matrix()`](http://www.rdocumentation.org/packages/base/functions/matrix). Ví dụ như dưới đây: 12 | 13 | ``` 14 | matrix(1:9, byrow = TRUE, nrow = 3) 15 | ``` 16 | 17 | Trong hàm [`matrix()`](http://www.rdocumentation.org/packages/base/functions/matrix) có những tham số sau: 18 | 19 | - Tham số đầu tiên là 1 tập hợp các yếu tố mà bạn muốn yêu cầu R sắp xếp thành hàng và cột trong ma trận đó. Trong ví dụ trên, `1:9` được hiểu là viết tắt của `c(1, 2, 3, 4, 5, 6, 7, 8, 9)`. 20 | - Tham số `byrow` thể hiện ma trận này được cập nhật theo từng dòng một. Nếu muốn ma trận đó đc cập nhật theo từng cột một, ta chỉ việc đặt `byrow = FALSE`. 21 | - Tham số thứ ba `nrow` số dòng của ma trận. 22 | 23 | *** =instructions 24 | Xây dựng một ma trận gồm 3 dòng để chứa các số từ 1 đến 9, cập nhật theo từng dòng một. 25 | 26 | *** =hint 27 | Bạn đọc kỹ hướng dẫn nhé, câu trả lời đã có sẵn rồi đấy! 28 | 29 | *** =pre_exercise_code 30 | ```{r} 31 | # no pec 32 | ``` 33 | 34 | *** =sample_code 35 | ```{r} 36 | # Xây dựng một ma trận gồm 3 dòng để chứa các số từ 1 đến 9 37 | ``` 38 | 39 | *** =solution 40 | ```{r} 41 | # Xây dựng một ma trận gồm 3 dòng để chứa các số từ 1 đến 9 42 | matrix(1:9, byrow = TRUE, nrow = 3) 43 | ``` 44 | 45 | *** =sct 46 | ```{r} 47 | test_function("matrix", c("data", "byrow", "nrow"), 48 | incorrect_msg = "Bạn đã tạo đúng ma trận chưa? Bạn đọc kỹ hướng dẫn nhé, câu trả lời đã được cho rồi đấy!") 49 | test_output_contains("matrix(1:9, byrow=TRUE, nrow=3)", 50 | incorrect_msg = "Hình như định nghĩa của ma trận có vấn đề. Bạn đọc kỹ hướng dẫn nhé, câu trả lời đã có sẵn rồi đấy!") 51 | success_msg("Tuyệt! Sang bài tập tiếp theo nào.") 52 | ``` 53 | 54 | 55 | --- type:NormalExercise xp:100 skills:1 key:effc2fb945 56 | ## Phân tích trong ma trận 57 | 58 | 59 | Đã đến lúc bắt tay vào việc chính. Trong bài tập sau đây, bạn sẽ phân tích doanh số vé bán ra của loạt phim đình đám: Star Wars. Chúc bạn may mắn! 60 | 61 | Trong trình soạn thảo, chúng ta có sẵn ba véc-tơ. Mỗi véc-tơ thể hiện doanh thu vé của một trong 3 bộ phim đầu tiên của Star Wars. Yếu tố đầu tiên của từng véc-tơ thể hiện doanh thu vé trong nội địa nước Mỹ, còn yếu tố thứ hai thể hiện doanh thu vé bán ngoài nước Mỹ. (nguồn: Wikipedia). 62 | 63 | Trong bài tập này, bạn sẽ kết hợp tất cả các con số này vào một véc-tơ duy nhất. Sau đó bạn sẽ sây dựng một ma trận từ véc-tơ đó. 64 | 65 | *** =instructions 66 | - Sử dụng `c(new_hope, empire_strikes, return_jedi)` để gộp ba véc-tơ này làm một. Đặt tên véc-tơ mới là `box_office`. 67 | - Xây dựng một ma trận có 3 dòng, mỗi dòng tượng trưng cho một bộ phim. Sử dụng hàm `matrix()` để làm điều này. Tham số đầu tiên là véc-tơ `box_office`,là véc-tơ chứa tất cả các thông tin về doanh thu. Tiếp đó, bạn đặt `nrow = 3` và `byrow = TRUE`. Đặt tên cho ma trận mới là `star_wars_matrix`. 68 | 69 | *** =hint 70 | - `box_office <- c(new_hope, empire_strikes, return_jedi)`sẽ gộp dữ liệu từ các véc-tơ khác nhau vào thành một véc-tơ duy nhất có 6 yếu tố. 71 | - Sử dụng mẫu `matrix(box_office, nrow = ..., by_row ...)` để giải phần thứ hai của bài tập. 72 | 73 | *** =pre_exercise_code 74 | ```{r} 75 | # no pec 76 | ``` 77 | 78 | *** =sample_code 79 | ```{r} 80 | # Doanh thu vé Star Wars bán ra (theo đơn vị hàng triệu!) 81 | new_hope <- c(460.998, 314.4) 82 | empire_strikes <- c(290.475, 247.900) 83 | return_jedi <- c(309.306, 165.8) 84 | 85 | # Tạo box_office 86 | box_office <- 87 | 88 | # Xây dựng star_wars_matrix 89 | star_wars_matrix <- 90 | ``` 91 | 92 | *** =solution 93 | ```{r} 94 | # Doanh thu vé Star Wars bán ra (theo đơn vị hàng triệu!) 95 | new_hope <- c(460.998, 314.4) 96 | empire_strikes <- c(290.475, 247.900) 97 | return_jedi <- c(309.306, 165.8) 98 | 99 | # Tạo box_office 100 | box_office <- c(new_hope, empire_strikes, return_jedi) 101 | 102 | # Xây dựng star_wars_matrix 103 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE) 104 | ``` 105 | 106 | *** =sct 107 | ```{r} 108 | msg <- "Đừng thay đổi nội dung các biến `new_hope`, `empire_strikes` và `return_jedi`!" 109 | test_object("new_hope", undefined_msg = msg, incorrect_msg = msg) 110 | test_object("empire_strikes", undefined_msg = msg, incorrect_msg = msg) 111 | test_object("return_jedi", undefined_msg = msg, incorrect_msg = msg) 112 | 113 | test_object("box_office", incorrect_msg = "Bạn đã gộp đúng các giá trị trong `new_hope`, `empire_strikes` và `return_jedi` vào véc-tơ `box_office`? chưa") 114 | 115 | test_function("matrix", c("data", "nrow", "byrow"), 116 | incorrect_msg = "Bạn hãy nhớ đặt đúng các tham số trong hàm `matrix()`: `box_office`, `nrow = 3`, `by_row = TRUE`.") 117 | 118 | test_object("star_wars_matrix", 119 | incorrect_msg = "Bạn đã gán kết quả của câu lệnh `matrix()` cho `star_wars_matrix` chưa?") 120 | 121 | success_msg("Đúng là may mắn đang ở bên bạn! Sang bài tập tiếp theo nhé.") 122 | ``` 123 | 124 | 125 | --- type:NormalExercise xp:100 skills:1 key:f734e8bf74 126 | ## Đặt tên trong ma trận 127 | 128 | Để giúp mình nhớ được đã sử dụng `star_wars_matrix` để chứa những thông tin gì, bạn muốn dùng tên của các bộ phim để đặt cho từng dòng. Điều này không chỉ giúp bạn dễ đọc thông tin hơn, mà còn giúp bạn dễ dàng lọc ra những yếu tố mà bạn cần từ trong ma trận. 129 | 130 | Cũng giống như véc-tơ, bạn có thể đặt tên cho các dòng và cột trong ma trận. 131 | 132 | ``` 133 | rownames(my_matrix) <- row_names_vector 134 | colnames(my_matrix) <- col_names_vector 135 | ``` 136 | 137 | Chúng tôi đã chuẩn bị sẵn hai véc-tơ cho bạn là `region`, và `titles`. Bạn sẽ sử dụng 2 véc-tơ này để đặt tên cho cột và dòng trong `star_wars_matrix` theo thứ tự. 138 | 139 | *** =instructions 140 | - Sử dụng `colnames()` để đặt tên cho các cột trong `star_wars_matrix` với véc-tơ `region`. 141 | - Sử dụng `rownames()` để đặt tên cho các dòng trong `star_wars_matrix` với véc-tơ `titles`. 142 | - Hiển thị ra kết quả của `star_wars_matrix`. 143 | 144 | *** =hint 145 | Bạn có thể dùng `colnames(star_wars_matrix) <- region` để đặt tên cho các cột trong `star_wars_matrix`. Làm tương tự với các dòng. 146 | 147 | *** =pre_exercise_code 148 | ```{r} 149 | # no pec 150 | ``` 151 | 152 | *** =sample_code 153 | ```{r} 154 | # Doanh thu vé Star Wars bán ra (theo đơn vị hàng triệu!) 155 | new_hope <- c(460.998, 314.4) 156 | empire_strikes <- c(290.475, 247.900) 157 | return_jedi <- c(309.306, 165.8) 158 | 159 | # Xây dựng matrix 160 | star_wars_matrix <- matrix(c(new_hope, empire_strikes, return_jedi), nrow = 3, byrow = TRUE) 161 | 162 | # Lập 2 véc-tơ sẽ được đùng để đặt tên là region and titles 163 | region <- c("US", "non-US") 164 | titles <- c("A New Hope", "The Empire Strikes Back", "Return of the Jedi") 165 | 166 | # Đặt tên cho các cột với region 167 | 168 | 169 | # Đặt tên cho các dòng với titles 170 | 171 | 172 | # Hiển thị ra kết quả của star_wars_matrix 173 | ``` 174 | 175 | *** =solution 176 | ```{r} 177 | # Doanh thu vé Star Wars bán ra (theo đơn vị hàng triệu!) 178 | new_hope <- c(460.998, 314.4) 179 | empire_strikes <- c(290.475, 247.900) 180 | return_jedi <- c(309.306, 165.8) 181 | 182 | # Xây dựng matrix 183 | star_wars_matrix <- matrix(c(new_hope, empire_strikes, return_jedi), nrow = 3, byrow = TRUE) 184 | 185 | # Lập 2 véc-tơ sẽ được đùng để đặt tên là region and titles 186 | region <- c("US", "non-US") 187 | titles <- c("A New Hope", "The Empire Strikes Back", "Return of the Jedi") 188 | 189 | # Đặt tên cho các cột với region 190 | colnames(star_wars_matrix) <- region 191 | 192 | # Đặt tên cho các dòng với titles 193 | rownames(star_wars_matrix) <- titles 194 | 195 | # Hiển thị ra kết quả của star_wars_matrix 196 | star_wars_matrix 197 | ``` 198 | 199 | *** =sct 200 | ```{r} 201 | msg <- "Đừng thay đổi gì trong `new_hope`, `empire_strikes` và `return_jedi`!" 202 | test_object("new_hope", undefined_msg = msg, incorrect_msg = msg) 203 | test_object("empire_strikes", undefined_msg = msg, incorrect_msg = msg) 204 | test_object("return_jedi", undefined_msg = msg, incorrect_msg = msg) 205 | msg <- "Đừng sửa nội dung của `star_wars_matrix`; mà chỉ đặt tên cho các dòng và cột!" 206 | test_object("star_wars_matrix", incorrect_msg = msg) 207 | msg <- "Đừng thay đổi gì trong hai véc-tơ đã được cho sẵn là `region` và `titles`." 208 | test_object("region", undefined_msg = msg, incorrect_msg = msg) 209 | test_object("titles", undefined_msg = msg, incorrect_msg = msg) 210 | test_object("star_wars_matrix", eq_condition = "equal", 211 | incorrect_msg = "Bạn đã đặt đúng tên cột và dòng cho `star_wars_matrix` chưa? Sử dụng `colnames(star_wars_matrix) <- region` để đặt tên cột; làm điều tương tự với dòng.") 212 | test_output_contains("star_wars_matrix", incorrect_msg = "Đừng quên hiển thị ra kết quả của `star_wars_matrix` sau khi đã đặt tên xong.") 213 | success_msg("Tuyệt lắm! Bạn sắp thành một Jedi trong lĩnh vực R rồi đấy! Sang bài tập tiếp theo nào.") 214 | ``` 215 | 216 | 217 | --- type:NormalExercise xp:100 skills:1 key:3fd7499a12 218 | ## Tính tổng doanh thu vé trên toàn cầu 219 | Để trờ thành huyền thoại điện ảnh, một bộ phim phải đạt được doanh số bán vé toàn cầu "khủng" 220 | 221 | Muốn tính toán lợi nhuận của cả ba bộ phim Star Wars, ta cần phải tính tổng doanh thu chúng đạt được ở cả trong và ngoài nước Mỹ. 222 | 223 | Trong R, hàm [`rowSums()`](http://www.rdocumentation.org/packages/base/functions/colSums) giúp ta dễ dàng tính được tổng của từng dòng trong một ma trận. Để làm được điều đó, hàm này sẽ tạo một véc tơ mới: 224 | 225 | ``` 226 | rowSums(my_matrix) 227 | ``` 228 | 229 | *** =instructions 230 | Tính ra doanh số bán vé của ba bộ phim và chứa kết quả vào một véc-tơ mới tên là `worldwide_vector`. 231 | 232 | *** =hint 233 | `rowSums(star_wars_matrix)` sẽ tính tổng của từng dòng một, cho ra kết quả tổng doanh thu của từng bộ phim. 234 | 235 | *** =pre_exercise_code 236 | ```{r} 237 | # no pec 238 | ``` 239 | 240 | *** =sample_code 241 | ```{r} 242 | # Xây dựng ma trận star_wars_matrix 243 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 244 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 245 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 246 | c("US", "non-US"))) 247 | 248 | # Tính tổng doanh thu toàn cầu 249 | worldwide_vector <- 250 | ``` 251 | 252 | *** =solution 253 | ```{r} 254 | # Xây dựng ma trận star_wars_matrix 255 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 256 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 257 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 258 | c("US", "non-US"))) 259 | 260 | # Tính tổng doanh thu toàn cầu 261 | worldwide_vector <- rowSums(star_wars_matrix) 262 | ``` 263 | 264 | *** =sct 265 | ```{r} 266 | msg <- "Đừng sửa nội dung của các biến `box_office_all` và `star_wars_marix`được cho sẵn!" 267 | test_object("box_office", undefined_msg = msg, incorrect_msg = msg) 268 | test_object("star_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 269 | test_object("worldwide_vector", incorrect_msg = "Dùng hàm `rowSums()` với `star_wars_matrix` rồi lưu kết quả vào `worldwide_vector`.") 270 | success_msg("Làm tốt lắm! Sang bài tập tiếp theo nào.") 271 | ``` 272 | 273 | 274 | --- type:NormalExercise xp:100 skills:1 key:86b87a8545 275 | ## Thêm cột thông tin doanh thu vé toàn cầu 276 | 277 | Trong bài tập trước, bạn đã tính ra véc-tơ chứa doanh thu của cả ba bộ phim Star Wars. Nhưng véc-tơ này vẫn chưa được cho vào ma trận `star_wars_matrix`. 278 | 279 | Bạn có thể thêm một hoặc nhiều cột vào một ma trận với hàm [`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind) . Hàm này được sử dụng để ghép các ma trận và véc-tơ với nhau theo cột. Tham khảo ví dụ dưới đây: 280 | 281 | ``` 282 | big_matrix <- cbind(matrix1, matrix2, vector1 ...) 283 | ``` 284 | 285 | *** =instructions 286 | Biến `worldwide_vector` thành một cột mới trong `star_wars_matrix` và gán kết quả cho `all_wars_matrix`. Hãy sử dụng hàm [`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind) để làm điều này. 287 | 288 | *** =hint 289 | Trong bài tập này, ta phải đưa hai biến là `star_wars_matrix` và `worldwide_vector` vào `cbind()`, theo đúng thứ tự trên. Sau đó gán kết quả cho `all_wars_matrix`. 290 | 291 | *** =pre_exercise_code 292 | ```{r} 293 | # no pec 294 | ``` 295 | 296 | *** =sample_code 297 | ```{r} 298 | # Xây dựng ma trận star_wars_matrix 299 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 300 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 301 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 302 | c("US", "non-US"))) 303 | 304 | # Tổng doanh thu toàn cầu 305 | worldwide_vector <- rowSums(star_wars_matrix) 306 | 307 | # Dùng biến mới tạo worldwide_vector làm một cột mới của star_wars_matrix 308 | all_wars_matrix <- 309 | ``` 310 | 311 | *** =solution 312 | ```{r} 313 | # Xây dựng ma trận star_wars_matrix 314 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 315 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 316 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 317 | c("US", "non-US"))) 318 | 319 | # Tổng doanh thu toàn cầu 320 | worldwide_vector <- rowSums(star_wars_matrix) 321 | 322 | # Dùng biến mới tạo worldwide_vector làm một cột mới của star_wars_matrix 323 | all_wars_matrix <- cbind(star_wars_matrix, worldwide_vector) 324 | ``` 325 | 326 | *** =sct 327 | ```{r} 328 | msg <- "Đừng thay đổi nội dung của các biến `box_office_all` và `star_wars_marix` đã được cho sẵn!" 329 | test_object("box_office", undefined_msg = msg, incorrect_msg = msg) 330 | test_object("star_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 331 | test_object("worldwide_vector", 332 | incorrect_msg = "Chứa kết quả của `rowSums(star_wars_matrix)` vào trong `worldwide_vector`.") 333 | 334 | msg <- "Bạn đã sử dụng `cbind()` một cách chính xác để đưa `worldwide_vector` vào `star_wars_matrix`? Bạn phải đưa `star_wars_matrix` và `world_wide_vector` vào hàm `cbind()` theo đúng thứ tự trên. Ma trận mới `all_wars_matrix` phải có ba dòng và 3 cột." 335 | test_object("all_wars_matrix", incorrect_msg = msg) 336 | success_msg("Làm tốt lắm! Sau khi thêm cột và ma trận thì bước tiếp theo hiển nhiên là thêm dòng. Chúng ta sẽ học cách làm điều đó trong bài tập tiếp theo.") 337 | ``` 338 | 339 | 340 | --- type:NormalExercise xp:100 skills:1 key:bcadb29139 341 | ## Thêm dòng 342 | 343 | Đã có bên trái thì ắt phải có bên phải, đã có hàm [`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind) thì phải có hàm [`rbind()`](http://www.rdocumentation.org/packages/base/functions/cbind). 344 | 345 | Tại workspace trong R, nơi chứa tất cả các đối tượng bạn đã khai báo, ([tìm hiểu thêm về định nghĩa của workspace tại đây](http://www.statmethods.net/interface/workspace.html)), có hai ma trận được tạo sau đây: 346 | 347 | - Ma trận `star_wars_matrix` là ma trận chúng ta đã sử dụng trong các bài tập ở phân trước, chứa thông tin của ba tập phim đầu, 348 | - Ma trận `star_wars_matrix2`chứa dữ liệu tương tự của ba tập phim tiếp theo. 349 | 350 | Gõ tên của các ma trận này trong console để nắm rõ hơn về chúng. Nếu bạn muốn xem nội dung của workspace, bạn cũng có thể gõ lệnh `ls()` vào console. 351 | 352 | *** =instructions 353 | Sử dụng `rbind()` để gộp `star_wars_matrix` và `star_wars_matrix2`, theo thứ tự trên. Gán kết quả vào ma trận `all_wars_matrix`. 354 | 355 | *** =hint 356 | Dùng lệnh dưới đây để gộp hai ma trận với nhau: 357 | ``` 358 | rbind(matrix1, matrix2) 359 | ``` 360 | Gán kết quả vào `all_wars_matrix`. 361 | 362 | 363 | *** =pre_exercise_code 364 | ```{r} 365 | # Xây dựng ma trận đầu tiên 366 | box_office_all <- c(461, 314.4, 290.5, 247.9, 309.3, 165.8) 367 | movie_names <- c("A New Hope","The Empire Strikes Back","Return of the Jedi") 368 | col_titles <- c("US","non-US") 369 | star_wars_matrix <- matrix(box_office_all, nrow = 3, byrow = TRUE, dimnames = list(movie_names, col_titles)) 370 | 371 | # Xây dựng ma trận thứ 2 372 | box_office_all2 <- c(474.5, 552.5, 310.7, 338.7, 380.3, 468.5) 373 | movie_names2 <- c("The Phantom Menace", "Attack of the Clones", "Revenge of the Sith") 374 | star_wars_matrix2 <- matrix(box_office_all2, nrow=3, byrow = TRUE, dimnames = list(movie_names2, col_titles)) 375 | 376 | # Xóa tất cả dữ liệu, chỉ để lại all_wars_matrix 377 | rm(box_office_all) 378 | rm(movie_names) 379 | rm(col_titles) 380 | rm(box_office_all2) 381 | rm(movie_names2) 382 | ``` 383 | 384 | *** =sample_code 385 | ```{r} 386 | # Workspace của bạn hiện đang có star_wars_matrix và star_wars_matrix2 387 | star_wars_matrix 388 | star_wars_matrix2 389 | 390 | # Tổng hợp cả sáu bộ phim Star Wars trong một ma trận 391 | all_wars_matrix <- 392 | ``` 393 | 394 | *** =solution 395 | ```{r} 396 | # Workspace của bạn hiện đang có star_wars_matrix và star_wars_matrix2 397 | star_wars_matrix 398 | star_wars_matrix2 399 | 400 | # Tổng hợp cả sáu bộ phim Star Wars trong một ma trận 401 | all_wars_matrix <- rbind(star_wars_matrix, star_wars_matrix2) 402 | ``` 403 | 404 | *** =sct 405 | ```{r} 406 | msg = "Đừng thay đổi nội dung của các biến đã được cho sẵn (`star_wars_matrix` and `star_wars_matrix2`)." 407 | test_object("star_wars_matrix", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 408 | test_object("star_wars_matrix2", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 409 | test_object("all_wars_matrix", incorrect_msg = "Bạn đã sử dụng hàm `rbind()` một cách chính xác để tạo ma trận `all_wars_matrix()`? `rbind()` phải chứa hai tham số là `star_wars_matrix` and `star_wars_matrix2`, theo đúng thứ tự đó.") 410 | 411 | success_msg("Tuyệt vời! Ở bài tập tiếp đây bạn sẽ học cách tổng hợp kết quả của hai hàm `rbind()` và `colSums()`!") 412 | ``` 413 | 414 | 415 | --- type:NormalExercise xp:100 skills:1 key:1bfe5ae096 416 | ## Tổng doanh thu bán vé của cả bộ sáu tập phim Star Wars 417 | 418 | Đã có hàm [`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind) thì phải có hàm [`rbind()`](http://www.rdocumentation.org/packages/base/functions/cbind). Tương tụ như vậy, đã có hàm [`colSums()`](http://www.rdocumentation.org/packages/base/functions/colSums) thì phải có hàm [`rowSums()`](http://www.rdocumentation.org/packages/base/functions/colSums). Workspace trong R của bạn đã có sẵn ma trận `all_wars_matrix` là ma trận đã được tạo trong bài tập trước đó; để xem lại nội dung của ma trận này ta gõ `all_wars_matrix`. Đã đến lúc tính tổng doanh thu bán vé của cả bộ sáu tập phim Star Wars. 419 | 420 | *** =instructions 421 | - Tính tổng doanh thu bộ phim cả trong và ngoài nước Mỹ, rồi gán kết quả đó cho `total_revenue_vector`. Để làm điều đó, ta sử dụng hàm [`colSums()`](http://www.rdocumentation.org/packages/base/functions/colSums). 422 | - Hiển thị kết quả của `total_revenue_vector`. 423 | 424 | *** =hint 425 | Bạn hãy dùng hàm [`colSums()`](http://www.rdocumentation.org/packages/base/functions/colSums) có tham số là `star_wars_matrix` để tính tổng doanh thu từng vùng. 426 | 427 | *** =pre_exercise_code 428 | ```{r} 429 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 430 | ``` 431 | 432 | *** =sample_code 433 | ```{r} 434 | # all_wars_matrix đã được cho sẵn trong workspace của bạn 435 | all_wars_matrix 436 | 437 | # Tổng doanh thu bán vé ở trong và ngoài nước Mỹ 438 | total_revenue_vector <- 439 | 440 | # Hiển thị kết quả của total_revenue_vector 441 | ``` 442 | 443 | *** =solution 444 | ```{r} 445 | # all_wars_matrix đã được cho sẵn trong workspace của bạn 446 | all_wars_matrix 447 | 448 | # Tổng doanh thu bán vé ở trong và ngoài nước Mỹ 449 | total_revenue_vector <- colSums(all_wars_matrix) 450 | 451 | # Hiển thị kết quả của total_revenue_vector 452 | total_revenue_vector 453 | ``` 454 | 455 | *** =sct 456 | ```{r} 457 | msg = "Đừng thay đổi nội dung của `all_wars_matrix`đã được cho sẵn trong workspace." 458 | test_object("all_wars_matrix", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 459 | test_function("colSums", "x", incorrect_msg = "Bạn đã sử dụng hàm `colSums()` để biến đổi ma trận all_wars_matrix?") 460 | test_object("total_revenue_vector", 461 | incorrect_msg = "Bạn đã gán đúng kết quả của câu lệnh `colSums(all_wars_matrix)` cho `total_revenue_vector`?") 462 | test_output_contains("total_revenue_vector", incorrect_msg = "Nhớ hiển thị kết quả cho `total_revenue_vector`!") 463 | success_msg("Tốt lắm! Sang bài tập tiếp theo để học cách tạo tập con cho ma trận.") 464 | ``` 465 | 466 | 467 | --- type:NormalExercise xp:100 skills:1 key:41d9d69713 468 | ## Lọc dữ liệu trong ma trận 469 | 470 | Cũng giống như khi làm việc với véc-tơ, ta có thể sử dụng các dấu ngoặc vuông `[ ]` để lọc một hoặc nhiều dữ liệu từ một ma trận. Điểm khác biệt giữa véc-tơ và ma trận là véc-tơ chỉ có một chiều, trong khi ma trận thì có 2 chiều. Vì vậy, ta sẽ sử dụng dấu phẩy để phân biệt giữa dữ liệu được chọn theo dòng và dữ liệu được chọn theo cột. Xem các ví dụ sau: 471 | 472 | - Câu lệnh `my_matrix[1,2]` sẽ chọn dữ liệu ở dòng thứ nhất và cột thứ hai. 473 | - Câu lệnh `my_matrix[1:3,2:4]` sẽ cho ra kết quả một ma trận gồm dữ liệu của dòng thứ 1, 2, 3 và cột thứ 2, 3, 4. 474 | 475 | Nếu bạn muốn chọn tất cả các dữ liệu của một dòng hoặc một cột, bạn chỉ cần để trống phần phía trước hoặc phía sau dấu phẩy, theo đúng thứ tự trên: 476 | 477 | - `my_matrix[,1]` chọn tất cả các dữ liệu thuộc cột thứ nhất. 478 | - `my_matrix[1,]` chọn tất cả các dữ liệu thuộc dòng thứ nhất. 479 | 480 | Chúng ta hãy cùng trở lại với ví dụ Star Wars nhé! Giống với bài tập trước, bạn đã được cho sẵn `all_wars_matrix` trong workspace. 481 | 482 | *** =instructions 483 | - Chọn doanh thu ngoài nước Mỹ của tất cả các bộ phim (đồng nghĩa với lấy toàn bộ cột thứ hai của `all_wars_matrix`), gán kết quả cho `non_us_all`. 484 | - Sử dụng lệnh `mean()` cho `non_us_all` để tính doanh thu trung bình ở ngoài Mỹ của tất cả các bộ phim. Sau đó hiển thị kết quả đã tính được. 485 | - Tiếp đến, lọc ra doanh thu ngoài nước Mỹ của 2 tập phim đầu tiên trong `all_wars_matrix`. Gán kết quả đó cho `non_us_some`. 486 | - Sử dụng lệnh `mean()` để tính trung bình các giá trị trong `non_us_some`. 487 | 488 | *** =hint 489 | Để lấy toàn bộ cột thứ hai của một ma trận `my_matrix`, bạn sử dụng `my_matrix[,2]`. 490 | 491 | *** =pre_exercise_code 492 | ```{r} 493 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 494 | ``` 495 | 496 | *** =sample_code 497 | ```{r} 498 | # all_wars_matrix đã được cho sẵn trong workspace của bạn 499 | all_wars_matrix 500 | 501 | # Tìm doanh thu ngoài nước Mỹ của tất cả các bộ phim 502 | non_us_all <- 503 | 504 | # Doanh thu trung bình ở ngoài nước Mỹ 505 | 506 | 507 | # Tìm doanh thu ngoài nước Mỹ của hai bộ phim đầu tiên 508 | non_us_some <- 509 | 510 | # Doanh thu trung bình ở ngoài nước Mỹ cho hai bộ phim đầu tiên 511 | 512 | ``` 513 | 514 | *** =solution 515 | ```{r} 516 | # all_wars_matrix đã được cho sẵn trong workspace của bạn 517 | all_wars_matrix 518 | 519 | # Tìm doanh thu ngoài nước Mỹ của tất cả các bộ phim 520 | non_us_all <- all_wars_matrix[,2] 521 | 522 | # Doanh thu trung bình ở ngoài nước Mỹ 523 | mean(non_us_all) 524 | 525 | # Tìm doanh thu ngoài nước Mỹ của hai bộ phim đầu tiên 526 | non_us_some <- all_wars_matrix[1:2,2] 527 | 528 | # Doanh thu trung bình ở ngoài nước Mỹ cho hai bộ phim đầu tiên 529 | mean(non_us_some) 530 | ``` 531 | 532 | *** =sct 533 | ```{r} 534 | msg = "Đừng thay đổi nội dung của `all_wars_matrix`đã được cho sẵn trong workspace." 535 | test_object("all_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 536 | 537 | test_object("non_us_all", 538 | incorrect_msg = "Bạn đã gán cho `non_us_all` dữ liệu của cả cột thứ hai của `all_wars_matrix`? Để làm điều đó bạn dùng `[, 2]`") 539 | test_output_contains("mean(non_us_all)", 540 | incorrect_msg = "Bạn đã tính giá trị trung bình của các giá trị trong `non_us_all` bằng cách dùng hàm `mean(non_us_all)` chưa? Nhớ hiển thị ra kết quả cuối cùng nhé.") 541 | test_object("non_us_some", 542 | incorrect_msg = "Bạn đã gán doanh thu ngoài nước Mỹ của hai bộ phim đầu tiên cho `non_us_some` chưa? Để làm điều đó bạn dùng `[1:2,2]`") 543 | test_output_contains("mean(non_us_some)", 544 | incorrect_msg = "Bạn đã tính trung bình của các giá trị trong `non_us_some` bằng `mean(non_us_some)`? Nhớ hiển thị ra kết quả cuối cùng nhé.") 545 | success_msg("Tuyệt vời! Cùng sang bài tập tiếp theo nhé.") 546 | ``` 547 | 548 | 549 | --- type:NormalExercise xp:100 skills:1 key:c81c656f06 550 | ## Cách làm phép tính trong ma trận 551 | 552 | Tương tự như những gì bạn đã học về véc-tơ, các dấu tính `+`, `-`, `/`, `*`, v.v... cũng được áp dụng để tính toán theo từng yếu tố riêng lẻ trong R. 553 | 554 | Ví dụ, `2 * my_matrix` sẽ nhân từng yếu tố trong `my_matrix` với số 2. 555 | 556 | Với vai trò là một chuyên viên phân tích dữ liệu mới của Lucasfilm, bạn được giao trách nhiệm tính số lượng người đi xem phim của từng bộ phim tại từng vùng địa lý. Bạn đã có số liệu về tổng doanh thu trong ma trận `all_wars_matrix`. Giả định giá vé là 5 đô-la-Mỹ cho một vé. Bạn hãy chia doanh thu cho giá vé để tính số lượng người đi xem phim. 557 | 558 | *** =instructions 559 | - Chia `all_wars_matrix` cho 5, bạn sẽ nhận được số lượng người đi xem phim theo đơn vị hàng triệu. Gán ma trận đạt được cho `visitors`. 560 | - Hiển thị kết quả cho `visitors`. 561 | 562 | *** =hint 563 | Số lượng người đi xem phim bằng `all_wars_matrix` chia cho 5. 564 | 565 | *** =pre_exercise_code 566 | ```{r} 567 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 568 | ``` 569 | 570 | *** =sample_code 571 | ```{r} 572 | # all_wars_matrix đã được cho sẵn trong workspace của bạn 573 | all_wars_matrix 574 | 575 | # Tính số lượng người đi xem phim 576 | visitors <- 577 | 578 | # Hiển thị kết quả lên console 579 | 580 | ``` 581 | 582 | *** =solution 583 | ```{r} 584 | # all_wars_matrix đã được cho sẵn trong workspace của bạn 585 | all_wars_matrix 586 | 587 | # Tính số lượng người đi xem phim 588 | visitors <- all_wars_matrix / 5 589 | 590 | # Hiển thị kết quả lên console 591 | visitors 592 | ``` 593 | 594 | *** =sct 595 | ```{r} 596 | msg = "Đừng thay đổi nội dung của `all_wars_matrix`đã được cho sẵn trong workspace." 597 | test_object("all_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 598 | 599 | test_object("visitors", 600 | incorrect_msg = "Hình như kết quả của `visitors` là chưa chính xác. Bạn chỉ cần chia `all_wars_matrix` cho 5 và gán kết quả đó cho `visitors`.") 601 | test_output_contains("visitors", incorrect_msg = "Đừng quên hiển thị kết quả cho `visitors`.") 602 | success_msg("Tuyệt lắm! Bạn đọc được gì từ kết quả ở trên? Có tận 92 triệu người đã đi xem phim A New Hope tại các rạp chiếu phim ở Mỹ! Cùng sang bài tập tiếp theo nhé.") 603 | ``` 604 | 605 | 606 | --- type:NormalExercise xp:100 skills:1 key:1e0b39d6e9 607 | ## Cách làm phép tính trong ma trận (2) 608 | 609 | Nếu như phép tính `2 * my_matrix` giúp ta nhân từng yếu tố trong `my_matrix` cho 2, `my_matrix1 * my_matrix2` sẽ tạo ra một ma trận trong đó mỗi yếu tố là tích của từng yếu tố tương tự trong `my_matrix1` và `my_matrix2`. 610 | 611 | Sau khi đọc kết quả của bài tập vừa rồi, sếp tổng Lucas chỉ ra việc giá vé có tăng qua từng thời kỳ. Sếp ra chỉ thị làm lại bản phân tích này dựa vào giá vé trong ma trận `ticket_prices_matrix` (nguồn: imagination). 612 | 613 | _Bạn nên nhớ rằng đây không phải là một phép tính nhân ma trận thuần túy. Nếu muốn tính nhân trong ma trận trong R bạn phải sử dụng dấu `%*%`._ 614 | 615 | *** =instructions 616 | - Chia `all_wars_matrix` cho `ticket_prices_matrix` để tính số lượng người xem phim ở trong và ngoài nước Mỹ của sáu bộ phim. Gán kết quả cho `visitors`. 617 | - Từ ma trận `visitors`, hãy chọn cả cột đầu tiên, tức là cột số lượng người đi xem phim tại Mỹ. Gán kết quả này cho `us_visitors`. 618 | - Tính số lượng người đi xem phim trung bình tại Mỹ; sau đó hiển thị kết quả. 619 | 620 | *** =hint 621 | - Bạn có thể dùng hàm `mean()` để tính bình quân các giá trị. 622 | - Muốn lấy số người xem phim tại Mỹ, chọn cột đầu tiên của `visitors` với `visitors[ ,1]`. 623 | 624 | *** =pre_exercise_code 625 | ```{r} 626 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 627 | movie_names <- c("A New Hope","The Empire Strikes Back","Return of the Jedi", "The Phantom Menace", "Attack of the Clones", "Revenge of the Sith") 628 | col_titles <- c("US","non-US") 629 | ticket_prices_matrix <- matrix(c(5, 5, 6, 6, 7, 7, 4, 4, 4.5, 4.5, 4.9, 4.9), nrow = 6, byrow = TRUE, dimnames = list(movie_names,col_titles)) 630 | ``` 631 | 632 | *** =sample_code 633 | ```{r} 634 | # Các ma trận all_wars_matrix và ticket_prices_matrix đã được cho sẵn 635 | all_wars_matrix 636 | ticket_prices_matrix 637 | 638 | # Số lượng người xem phim 639 | visitors <- 640 | 641 | # Số lượng người xem phim tại Mỹ 642 | us_visitors <- 643 | 644 | # Bình quân số lượng người xem phim tại Mỹ 645 | 646 | ``` 647 | 648 | *** =solution 649 | ```{r} 650 | # Các ma trận all_wars_matrix và ticket_prices_matrix đã được cho sẵn 651 | all_wars_matrix 652 | ticket_prices_matrix 653 | 654 | # Số lượng người xem phim 655 | visitors <- all_wars_matrix / ticket_prices_matrix 656 | 657 | # Số lượng người xem phim tại Mỹ 658 | us_visitors <- visitors[ ,1] 659 | 660 | # Bình quân số lượng người xem phim tại Mỹ 661 | mean(us_visitors) 662 | ``` 663 | 664 | *** =sct 665 | ```{r} 666 | msg <- "Đừng thay đổi nội dung của `all_wars_matrix`đã được cho sẵn trong workspace." 667 | test_object("all_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 668 | test_object("ticket_prices_matrix", undefined_msg = msg, incorrect_msg = msg) 669 | 670 | test_object("visitors", 671 | incorrect_msg = "Bạn đã tạo chính xác ma trận `visitors` matrix? Bạn chỉ cần chia `all_wars_matrix` cho `ticket_prices_matrix`.") 672 | test_object("us_visitors", incorrect_msg = "Để tạo `us_visitors`, bạn phải chọn tất cả dữ liệu của cột đầu tiên trong `visitors`. Để làm được điều đó hãy dùng `[,1]`!") 673 | test_output_contains("mean(us_visitors)", incorrect_msg = "Sau khi bạn đã tạo `us_visitors`, hãy dùng `mean()` để tính số lượng người xem phim tại Mỹ. Hãy nhớ hiển thị kết quả tính được.") 674 | 675 | success_msg("Chương về ma trận đến đây là kết thúc. Tại chương tiếp theo bạn sẽ được tiếp xúc với một khái niệm khác trong ngôn ngữ R, đó là factor.") 676 | ``` 677 | 678 | 679 | -------------------------------------------------------------------------------- /chapter2.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : Chương 2 3 | title : Véc-tơ 4 | description : "Trong chương tiếp theo trong khóa học này, chúng ta sẽ cùng đến thăm Vegas, tại đây bạn sẽ được học cách sử dụng vec-tơ trong R để phân tích kết quả bài bạc của bản thân! Sau khi hoàn thành chương này, bạn sẽ học được cách khởi tạo, đặt tên, lọc các yếu tố và so sánh các véc-tơ trong R." 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:d9b453dbdd 7 | ## Tạo một véc-tơ 8 | 9 | Bạn có nghĩ rằng mình được thần may mắn chiếu cố không? Có lẽ bạn sẽ muốn vậy đấy, bởi lẽ trong chương này bạn sẽ được đến thăm Vegas - thành phố của dục vọng, hay cũng còn được gọi là *Thiên đường của các nhà thống kê học*! 10 | 11 | Nhờ có R cũng như khả năng phân tích số liệu mới học, bạn sẽ được học cách nâng cao trình độ cá cược của bản thân và bắt đầu con đường bài bạc chuyên nghiệp. Trong chương này, bạn sẽ học được cách theo dõi quá trình cá cược của bản thân cũng như phương pháp thực hiện một vài phân tích đơn giản từ dữ liệu trong quá khứ. Cùng thẳng tiến tới Vegas nào!! 12 | 13 | *** =instructions 14 | - Bạn còn nhớ những kiến thức bạn được học trong chương 1 không? Gán giá trị `"Go!"` cho biến `vegas`. Nhớ là R phân biệt chữ hoa và chữ thường nhé! 15 | 16 | *** =hint 17 | Hãy gõ câu lệnh sau vào trình soạn thảo (editor): 18 | 19 | ``` 20 | vegas <- "Go!" 21 | ``` 22 | 23 | *** =pre_exercise_code 24 | ```{r} 25 | # no pec 26 | ``` 27 | 28 | *** =sample_code 29 | ```{r} 30 | # Định nghĩa biến vegas 31 | vegas <- 32 | ``` 33 | 34 | *** =solution 35 | ```{r} 36 | # Định nghĩa biến vegas 37 | vegas <- "Go!" 38 | ``` 39 | 40 | *** =sct 41 | ```{r} 42 | test_object("vegas", incorrect_msg = "Đừng quên gán đúng giá trị cho biến `vegas`. Đừng quên là R phân biệt chữ hoa và chữ thường nhé!") 43 | success_msg("Tuyệt lắm! Sang bài tập tiếp theo nào.") 44 | ``` 45 | 46 | 47 | --- type:NormalExercise xp:100 skills:1 key:fd427db76f 48 | ## Tạo một véc-tơ (2) 49 | 50 | Trên con đường trở thành triệu phú, bạn sẽ thường xuyên sử dụng các véc-tơ. Véc-tơ là các chuỗi 1 chiều, được dùng để chứa dữ liệu số, ký tự hoặc lôgic. Nói cách khác, véc-tơ là một công cụ đơn giản để chứa dữ liệu. Ví dụ, bạn có thể dùng chúng để lưu trữ thông tin lời lỗ hàng ngày mà bạn kiếm được tại sòng bạc. 51 | 52 | Trong R, bạn sử dụng hàm kết hợp[`c()`](http://www.rdocumentation.org/packages/base/functions/c) để tạo véc-tơ. Bạn sẽ dùng các dấu phẩy để nối các yếu tố của véc-tơ với nhau, và đặt chúng ở giữa hai dấu ngoặc. Xem ví dụ dưới đây: 53 | 54 | ``` 55 | numeric_vector <- c(1, 2, 3) 56 | character_vector <- c("a", "b", "c") 57 | ``` 58 | 59 | Sau khi bạn đã tạo các véc-tơ trong R, bạn có thể sử dụng chúng để tính toán. 60 | 61 | *** =instructions 62 | Hoàn thành câu lệnh để thể hiện rằng véc-tơ `boolean_vector` bao gồm 3 yếu tố: `TRUE`, `FALSE` và `TRUE` (với thứ tự như trên). 63 | 64 | *** =hint 65 | Gán `c(TRUE, FALSE, TRUE)` cho biến `boolean_vector` bằng dấu `<-`. 66 | 67 | *** =pre_exercise_code 68 | ```{r} 69 | # no pec 70 | ``` 71 | 72 | *** =sample_code 73 | ```{r} 74 | numeric_vector <- c(1, 10, 49) 75 | character_vector <- c("a", "b", "c") 76 | 77 | # Hoàn thành câu lệnh cho boolean_vector 78 | boolean_vector <- 79 | ``` 80 | 81 | *** =solution 82 | ```{r} 83 | numeric_vector <- c(1, 10, 49) 84 | character_vector <- c("a", "b", "c") 85 | 86 | # Hoàn thành câu lệnh cho boolean_vector 87 | boolean_vector <- c(TRUE, FALSE, TRUE) 88 | ``` 89 | 90 | *** =sct 91 | ```{r} 92 | msg <- "Đừng sửa câu lệnh được dùng để định nghĩa `numeric_vector` và `character_vector`!" 93 | test_object("numeric_vector", undefined_msg = msg, incorrect_msg = msg) 94 | test_object("character_vector", undefined_msg = msg, incorrect_msg = msg) 95 | test_object("boolean_vector", 96 | incorrect_msg = "Hãy gán các giá trị đúng cho `boolean_vector`. Dùng `c(TRUE, FALSE, TRUE)`. Đừng dùng dấu ngoặc kép cho `TRUE` và `FALSE`! Ngoài ra, hãy nhớ sử dụng đúng thứ tự như trong phần hướng dẫn.") 97 | success_msg("Hoàn hảo! Bạn có thấy là khi ta đặt một khoảng cách giữa những dấu phẩy trong hàm `c()` thì câu lệnh sẽ dễ nhìn hơn không. Chúng ta sẽ luyện tập tiếp về việc tạo véc-tơ trong bài tập tiếp theo.") 98 | ``` 99 | 100 | 101 | --- type:NormalExercise xp:100 skills:1 key:9f41229dbc 102 | ## Tạo một véc-tơ (3) 103 | 104 | Sau một tuần ở Las Vegas mà vẫn chưa mua được chiếc Ferrari nào, bạn quyết định đã đến lúc áp dụng siêu năng lực phân tích dữ liệu của mình. 105 | 106 | Trước khi bắt đầu phân tích, bạn quyết định tìm thông tin về tất cả các lần thắng thua của tuần trước: 107 | 108 | Với `poker_vector`: 109 | 110 | - Thứ Hai bạn thắng $140 111 | - Thứ Ba bạn thua $50 112 | - Thứ Tư bạn thắng $20 113 | - Thứ Năm bạn thua $120 114 | - Thứ Sáu bạn thắng $240 115 | 116 | Với `roulette_vector`: 117 | 118 | - Thứ Hai bạn thua $24 119 | - Thứ Ba bạn thua $50 120 | - Thứ Tư bạn thắng $100 121 | - Thứ Năm bạn thua $350 122 | - Thứ Sáu bạn thắng $10 123 | 124 | Vì các bàn chơi trò xúc xắc đã đầy người nên bạn chỉ chơi bài poker và rulet. Để dùng dữ liệu này trong R, bạn quyết định tạo các biến `poker_vector` và `roulette_vector`. 125 | 126 | *** =instructions 127 | Gán dữ liệu thắng thua của trò rulet cho biến `roulette_vector`. 128 | 129 | *** =hint 130 | Trong trình soạn thảo đã có sẵn câu lệnh dùng để tạo `poker_vector`. Gán các giá trị đúng cho `roulette_vector` dựa vào các con số đã được cho ở phần đề bài. Đừng quên đặt dữ liệu thua ở dạng số âm. 131 | 132 | *** =sample_code 133 | ```{r} 134 | # Dữ liệu thắng thua của trò poker từ thứ Hai đến thứ Sáu 135 | poker_vector <- c(140, -50, 20, -120, 240) 136 | 137 | # Dữ liệu thắng thua của trò rulet từ thứ Hai đến thứ Sáu 138 | roulette_vector <- 139 | ``` 140 | 141 | *** =solution 142 | ```{r} 143 | # Dữ liệu thắng thua của trò poker từ thứ Hai đến thứ Sáu 144 | poker_vector <- c(140, -50, 20, -120, 240) 145 | 146 | # Dữ liệu thắng thua của trò rulet từ thứ Hai đến thứ Sáu 147 | roulette_vector <- c(-24, -50, 100, -350, 10) 148 | ``` 149 | 150 | *** =sct 151 | ```{r} 152 | test_object("poker_vector", 153 | incorrect_msg = "Hãy nhớ đặt đúng các giá trị cho `poker_vector`.") 154 | test_object("roulette_vector", 155 | incorrect_msg = "Hãy nhớ đặt đúng các giá trị cho `roulette_vector`.Kiểm tra xem thứ tự đã đúng chưa!") 156 | success_msg("Tốt lắm! Để xem lại các véc-tơ của bạn chứa những gì, bạn chỉ cần gõ tên biến trong bảng điều khiển và nhấn Enter. Sang bài tập tiếp theo nào!") 157 | ``` 158 | 159 | 160 | --- type:NormalExercise xp:100 skills:1 key:3b0b80b192 161 | ## Đặt tên cho véc-tơ 162 | 163 | Là một chuyên viên phân tích dữ liệu, bạn phải hiểu mình đang dùng những dữ liệu nào. Việc hiểu ý nghĩa của từng yếu tố trong véc-tơ là rất quan trọng. 164 | 165 | Trong bài tập trước, ta đã dùng dữ liệu thắng thua của bạn để tạo một véc-tơ. Mỗi thành phần trong véc-tơ là số liệu của một ngày trong tuần, nhưng hơi khó để nhận biết yếu tố nào thuộc ngày nào. Sẽ tốt hơn nếu bạn có thể chỉ ra điều này trong chính véc-tơ đó. 166 | 167 | Bạn có thể đặt tên cho từng yếu tố của véc-tơ với hàm `names()`. Xem ví dụ dưới đây: 168 | 169 | ``` 170 | some_vector <- c("John Doe", "poker player") 171 | names(some_vector) <- c("Name", "Profession") 172 | ``` 173 | 174 | Các câu lệnh này đã tạo ra véc-tơ `some_vector` rồi đặt tên cho 2 thành phần trong véc-tơ. Yếu tố đầu tiên được đặt tên là `Name`, còn yếu tố thứ hai là `Profession`. Khi hiển thị trong màn hình tương tác bạn nhận được kết quả sau đây: 175 | 176 | ``` 177 | Name Profession 178 | "John Doe" "poker player" 179 | ``` 180 | 181 | *** =instructions 182 | - Câu lệnh ở bên phải sử dụng các ngày trong tuần để đặt tên cho các yếu tố trong `poker_vector`. Viết một câu lệnh khác để làm điều tương tự với `roulette_vector`. 183 | 184 | *** =hint 185 | Bạn có thể dùng `names(roulette_vector)` để đặt tên cho `roulette_vector`. Nhớ là dùng cùng một véc-tơ có các ngày trong tuần làm tên. Và cũng nhớ là R phân biệt giữa chữ hoa và chữ thường! 186 | 187 | *** =sample_code 188 | ```{r} 189 | # Dữ liệu thắng thua của trò poker từ thứ Hai đến thứ Sáu 190 | poker_vector <- c(140, -50, 20, -120, 240) 191 | 192 | # Dữ liệu thắng thua của trò rulet từ thứ Hai đến thứ Sáu 193 | roulette_vector <- c(-24, -50, 100, -350, 10) 194 | 195 | # Sử dụng các ngày trong tuần làm tên của poker_vector 196 | names(poker_vector) <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 197 | 198 | # Sử dụng các ngày trong tuần làm tên của roulette_vector 199 | ``` 200 | 201 | *** =solution 202 | ```{r} 203 | # Dữ liệu thắng thua của trò poker từ thứ Hai đến thứ Sáu 204 | poker_vector <- c(140, -50, 20, -120, 240) 205 | 206 | # Dữ liệu thắng thua của trò rulet từ thứ Hai đến thứ Sáu 207 | roulette_vector <- c(-24, -50, 100, -350, 10) 208 | 209 | # Sử dụng các ngày trong tuần làm tên của poker_vector 210 | names(poker_vector) <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 211 | 212 | # Sử dụng các ngày trong tuần làm tên của roulette_vectors 213 | names(roulette_vector) <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 214 | ``` 215 | 216 | *** =sct 217 | ```{r} 218 | test_object("poker_vector", 219 | incorrect_msg = "Đừng thay đổi giá trị bên trong `poker_vector`; đây là một câu lệnh mẫu.") 220 | test_object("roulette_vector", 221 | incorrect_msg = "Đừng thay đổi giá trị bên trong `roulette_vector`; đây là một câu lệnh mẫu.") 222 | test_object("poker_vector", 223 | eq_condition = "equal", 224 | incorrect_msg = "Đừng thay đổi câu lệnh dùng để đặt tên các yếu tố trong `poker_vector`; hãy tập trung vào `roulette_vector`!") 225 | test_object("roulette_vector", 226 | eq_condition = "equal", 227 | incorrect_msg = "Hãy nhớ dùng véc-tơ tên chính xác để đặt tên cho `roulette_vector`. Sử dụng chính véc-tơ đã được dùng để đặt tên cho `poker_vector`.") 228 | success_msg("Giỏi lắm! Sang bài tập tiếp theo nào.") 229 | ``` 230 | 231 | 232 | --- type:NormalExercise xp:100 skills:1 key:6858c65a4a 233 | ## Đặt tên cho véc-tơ (2) 234 | 235 | Nếu muốn trở thành một nhà thống kê học giỏi, bạn phải lười hơn một chút. (Nếu bạn vốn đã lười, nhiều khả năng bạn sở hữu tài năng thiên phú xuất chúng về mặt thống kê.) 236 | 237 | Trong các bài tập trước, bạn chắc đã cảm thấy vừa chán vừa bực mình khi phải viết đi viết lại một thông tin, ví dụ như thông tin các ngày trong tuần. Nhưng nếu bạn nhìn từ góc độ rộng hơn, thì còn có một cách làm hiệu quả hơn, đó là gán véc-tơ ngày trong tuần cho một **biến**! 238 | 239 | Giống hệt như những gì bạn đã làm với dữ liệu thắng thua của mình trong trò poker và rulet, bạn cũng có thể tạo ra một biến để chứa thông tin ngày trong tuần. Sau đó bạn có thể dùng đi dùng lại biến này. 240 | 241 | *** =instructions 242 | - Biến chứa thông tin các ngày trong tuần có tên là `days_vector` đã được tạo sẵn cho bạn. 243 | - Sử dụng `days_vector` để đặt tên cho `poker_vector` và `roulette_vector`. 244 | 245 | *** =hint 246 | Bạn có thể dùng `names(poker_vector) <- days_vector` để đặt tên cho các yếu tố trong `poker_vector`. Làm tương tự với `roulette_vector`. 247 | 248 | *** =pre_exercise_code 249 | ```{r} 250 | # no pec 251 | ``` 252 | 253 | *** =sample_code 254 | ```{r} 255 | # Dữ liệu thắng thua của trò poker từ thứ Hai đến thứ Sáu 256 | poker_vector <- c(140, -50, 20, -120, 240) 257 | 258 | # Dữ liệu thắng thua của trò rulet từ thứ Hai đến thứ Sáu 259 | roulette_vector <- c(-24, -50, 100, -350, 10) 260 | 261 | # Biến days_vector 262 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 263 | 264 | # Gán các ngày trong tuần cho tên của các yếu tố trong roulette_vector poker_vector 265 | names(poker_vector) <- 266 | names(roulette_vector) <- 267 | ``` 268 | 269 | *** =solution 270 | ```{r} 271 | # Dữ liệu thắng thua của trò poker từ thứ Hai đến thứ Sáu 272 | poker_vector <- c(140, -50, 20, -120, 240) 273 | 274 | # Dữ liệu thắng thua của trò rulet từ thứ Hai đến thứ Sáu 275 | roulette_vector <- c(-24, -50, 100, -350, 10) 276 | 277 | # Biến days_vector 278 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 279 | 280 | # Gán các ngày trong tuần cho tên của các yếu tố trong roulette_vector poker_vector 281 | names(poker_vector) <- days_vector 282 | names(roulette_vector) <- days_vector 283 | ``` 284 | 285 | *** =sct 286 | ```{r} 287 | msg <- "Đừng thay đổi nội dung của các biến `poker_vector`, `roulette_vector` hay là `days_vector`." 288 | test_object("poker_vector", undefined_msg = msg, incorrect_msg = msg) 289 | test_object("roulette_vector", undefined_msg = msg, incorrect_msg = msg) 290 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 291 | 292 | test_object("poker_vector", 293 | eq_condition = "equal", 294 | incorrect_msg = "Hãy nhớ gán `days_vector` làm tên của các yếu tố trong `poker_vector`.") 295 | test_object("roulette_vector", 296 | eq_condition = "equal", 297 | incorrect_msg = "Hãy nhớ gán `days_vector` làm tên của các yếu tố trong `roulette_vector`.") 298 | success_msg("Hay lắm! Data Camp có một lời khuyên nho nhỏ dành cho bạn, đó là nhất định phải tránh việc lặp lại các câu lệnh. Hãy sang bài tập tiếp theo để học các thực hiện các phép tính với véc-tơ nhé!") 299 | ``` 300 | 301 | 302 | --- type:NormalExercise xp:100 skills:1 key:da995f099f 303 | ## Tính tổng số tiền thắng thua 304 | 305 | Giờ thì bạn đã đặt được thông tin thắng thua trong các véc-tơ và đặt tên đầy đủ cho chúng, đã đến lúc sử dụng kỹ năng phân tích dữ liệu của mình. 306 | 307 | Bạn muốn tìm hiểu những thông tin dưới đây: 308 | 309 | - Từng ngày trong tuần bạn đã thắng bao nhiêu hoặc lỗ bao nhiêu? 310 | - Sau cả tuần cá cược bạn có mất đồng nào không? 311 | - Bạn chơi poker hoặc rulet thắng hay thua? 312 | 313 | Để biết câu trả lời, bạn cần sử dụng véc-tơ để làm tính toán. 314 | 315 | Bạn cần biết rằng khi cộng tổng hai véc-tơ trong R, R sẽ lấy tổng của từng yếu tố. Ví dụ, ba phép tính dưới đây sẽ cho chung một kết quả: 316 | 317 | ``` 318 | c(1, 2, 3) + c(4, 5, 6) 319 | c(1 + 4, 2 + 5, 3 + 6) 320 | c(5, 7, 9) 321 | ``` 322 | 323 | Bạn cũng có thể làm phép tính toán với các biến đại diện cho véc-tơ: 324 | 325 | ``` 326 | a <- c(1, 2, 3) 327 | b <- c(4, 5, 6) 328 | c <- a + b 329 | ``` 330 | 331 | *** =instructions 332 | - Tính tổng của các biến `A_vector` và `B_vector` sau đó gán kết quả cho `total_vector`. 333 | - Kiểm tra lại kết quả bằng cách hiển thị kết quả `total_vector`. 334 | 335 | *** =hint 336 | Sử dụng dấu `+` để tính tổng của `A_vector` và `B_vector`. Dùng `<-` để gán kết quả cho `total_vector`. 337 | 338 | *** =pre_exercise_code 339 | ```{r} 340 | # no pec 341 | ``` 342 | 343 | *** =sample_code 344 | ```{r} 345 | A_vector <- c(1, 2, 3) 346 | B_vector <- c(4, 5, 6) 347 | 348 | # Tính tổng của `A_vector` và `B_vector` 349 | total_vector <- 350 | 351 | # Hiển thị total_vector 352 | 353 | ``` 354 | 355 | *** =solution 356 | ```{r} 357 | A_vector <- c(1, 2, 3) 358 | B_vector <- c(4, 5, 6) 359 | 360 | # Tính tổng của A_vector và B_vector 361 | total_vector <- A_vector + B_vector 362 | 363 | # Hiển thị total_vector 364 | total_vector 365 | ``` 366 | 367 | *** =sct 368 | ```{r} 369 | msg <- "Đừng sửa nội dung của `A_vector` hoặc `B_vector`!" 370 | test_object("A_vector", undefined_msg = msg, incorrect_msg = msg) 371 | test_object("B_vector", undefined_msg = msg, incorrect_msg = msg) 372 | test_object("total_vector", incorrect_msg = "Hãy nhớ là `total_vector` phải chứa tổng của `A_vector` và `B_vector`.") 373 | test_output_contains("total_vector", incorrect_msg = "Đừng quên hiển thị `total_vector`! Bạn chỉ cần gõ `total_vector` trên một dòng mới.") 374 | success_msg("Tốt lắm! Hãy sang bài tập tiếp theo.") 375 | ``` 376 | 377 | 378 | --- type:NormalExercise xp:100 skills:1 key:2969d8ed65 379 | ## Tính tổng số tiền thắng thua (2) 380 | 381 | Giờ thì bạn đã hiểu cách R dùng véc-tơ để tính toán, đã đến lúc tăng bộ sưu tầm xe của bạn với những chiếc Ferrari rồi! Đầu tiên bạn phải nắm được thông tin lời lãi của từng ngày trong tuần. Tổng lời lãi hàng ngày là tổng lời lãi từng ngày của việc chơi poker và rulet. 382 | 383 | Trong R, đây thực chất là bài toán tổng của `roulette_vector` và `poker_vector`. 384 | 385 | *** =instructions 386 | Gán tổng lời lãi của mỗi ngày cho biến `total_daily` ( là tổng của cả poker và rulet). 387 | 388 | *** =hint 389 | Tương tự như bài tập trước, hãy gán tổng của hai véc-tơ cho một biến mới là biến `total_daily`. 390 | 391 | *** =pre_exercise_code 392 | ```{r} 393 | # no pec 394 | ``` 395 | 396 | *** =sample_code 397 | ```{r} 398 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 399 | poker_vector <- c(140, -50, 20, -120, 240) 400 | roulette_vector <- c(-24, -50, 100, -350, 10) 401 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 402 | names(poker_vector) <- days_vector 403 | names(roulette_vector) <- days_vector 404 | 405 | # Gán tổng lời lãi của mỗi ngày cho biến total_daily 406 | total_daily <- 407 | ``` 408 | 409 | *** =solution 410 | ```{r} 411 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 412 | poker_vector <- c(140, -50, 20, -120, 240) 413 | roulette_vector <- c(-24, -50, 100, -350, 10) 414 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 415 | names(poker_vector) <- days_vector 416 | names(roulette_vector) <- days_vector 417 | 418 | # Gán tổng lời lãi của mỗi ngày cho biến total_daily 419 | total_daily <- poker_vector + roulette_vector 420 | ``` 421 | 422 | *** =sct 423 | ```{r} 424 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 425 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 426 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 427 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 428 | 429 | test_object("total_daily", incorrect_msg = "Nhớ gán tổng của `poker_vector` và `roulette_vector` cho `total_daily`.") 430 | 431 | success_msg("Tuyệt! Sang bài tập tiếp theo nào.") 432 | ``` 433 | 434 | 435 | --- type:NormalExercise xp:100 skills:1 key:e66a56b9f0 436 | ## Tính tổng số tiền thắng thua (3) 437 | 438 | Dựa vào phân tích vừa rồi, có vẻ như là bạn có cả những ngày thắng và ngày thua. Bạn chưa lường trước được điều này, và tự hỏi liệu có chút khả năng nào là bạn đã thua tiền sau cả một tuần chơi? 439 | 440 | Để trả lời câu hỏi này bạn có thể dùng hàm [`sum()`](http://www.rdocumentation.org/packages/base/functions/sum). Hàm này tính tổng của tất cả các yếu tố trong một véc-tơ. Ví dụ, để tính tổng số tiền bạn đã thắng hoặc thua khi chơi poker bạn có thể gõ lệnh sau: 441 | 442 | ``` 443 | total_poker <- sum(poker_vector) 444 | ``` 445 | 446 | *** =instructions 447 | - Tính tổng số tiền bạn đã thắng hoặc thua khi chơi rulet và gán kết quả này cho `total_roulette`. 448 | - Giờ thì bạn đã có số tổng cho cả rulet lẫn poker, bạn có thể dễ dàng tính `total_week` (là tổng lỗ lãi từ việc thắng thua của cả tuần). 449 | - Hiển thị `total_week`. 450 | 451 | *** =hint 452 | Sử dụng hàm [`sum()`](http://www.rdocumentation.org/packages/base/functions/sum) để tính tổng cho `roulette_vector`. `total_week` là tổng của `roulette_vector` và `poker_vector`. 453 | 454 | *** =pre_exercise_code 455 | ```{r} 456 | # no pec 457 | ``` 458 | 459 | *** =sample_code 460 | ```{r} 461 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 462 | poker_vector <- c(140, -50, 20, -120, 240) 463 | roulette_vector <- c(-24, -50, 100, -350, 10) 464 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 465 | names(poker_vector) <- days_vector 466 | names(roulette_vector) <- days_vector 467 | 468 | # Tổng lời lãi từ việc chơi poker 469 | total_poker <- sum(poker_vector) 470 | 471 | # Tổng lời lãi từ việc chơi rulet 472 | total_roulette <- 473 | 474 | # Tổng lời lãi chung 475 | total_week <- 476 | 477 | # Hiển thị kết quả total_week 478 | 479 | ``` 480 | 481 | *** =solution 482 | ```{r} 483 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 484 | poker_vector <- c(140, -50, 20, -120, 240) 485 | roulette_vector <- c(-24, -50, 100, -350, 10) 486 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 487 | names(poker_vector) <- days_vector 488 | names(roulette_vector) <- days_vector 489 | 490 | # Tổng lời lãi từ việc chơi poker 491 | total_poker <- sum(poker_vector) 492 | 493 | # Tổng lời lãi từ việc chơi rulet 494 | total_roulette <- sum(roulette_vector) 495 | 496 | # Tổng lời lại chung 497 | total_week <- total_roulette + total_poker 498 | 499 | # Hiển thị kết quả total_week 500 | total_week 501 | ``` 502 | 503 | *** =sct 504 | ```{r} 505 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 506 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 507 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 508 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 509 | test_object("total_poker", 510 | incorrect_msg = "Nhớ gán tổng của `poker_vector` cho biến `total_poker`.") 511 | test_object("total_roulette", 512 | incorrect_msg = "Nhớ gán tổng của `roulette_vector` cho biến `total_roulette`.") 513 | test_object("total_week", 514 | incorrect_msg = "Nhớ gán tổng của 2 véc-tơ `total_roulette` và `total_poker` cho biến `total_week`.") 515 | 516 | test_output_contains("total_week", incorrect_msg = "Đừng quên gõ `total_week` trên một dòng mới để in giá trị của biến đó ra.") 517 | success_msg("Làm tốt lắm. Nhưng kết quả thì không được như mong đợi...") 518 | ``` 519 | 520 | 521 | --- type:NormalExercise xp:100 skills:1 key:f532f5332d 522 | ## So sánh tổng lời lãi thắng thua 523 | 524 | Té ra là bạn đang thua bạc. Bạn cần thay đổi chiến thuật của mình ngay! Nghĩ sâu hơn một chút nào... 525 | 526 | Sau một hồi suy nghĩ trong bể sục của khách sạn, bạn nhận ra một cách lý giải cho việc thua tiền là do bạn chơi rulet kém hơn chơi poker. Hình như bạn chơi poker thì kiếm đc nhiều tiền hơn (đồng nghĩa với dấu `>`) khi chơi rulet. 527 | 528 | *** =instructions 529 | - Tính `total_poker` và `total_roulette` giống bài tập trước. Sử dụng hàm `sum()` hai lần. 530 | - Dùng phép so sánh để kiểm tra xem có đúng bạn kiếm đc nhiều tiền khi chơi poker hơn là khi chơi rulet không?. Sau đó hiển thị ra kết quả của phép so sánh này. Bạn rút ra được kết luận gì? Bạn nên tập trung chơi rulet hay là poker? 531 | 532 | *** =hint 533 | - Bạn đã tính đc một phần của câu hỏi này trong bài tập trước rồi đấy! 534 | - Để kiểm tra xem có phải 6 lớn hơn 5 không, bạn gõ `6 > 5`. Bạn sẽ nhận lại 1 giá trị lôgic (`TRUE` hoặc `FALSE`). 535 | 536 | *** =pre_exercise_code 537 | ```{r} 538 | # no pec 539 | ``` 540 | 541 | *** =sample_code 542 | ```{r} 543 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 544 | poker_vector <- c(140, -50, 20, -120, 240) 545 | roulette_vector <- c(-24, -50, 100, -350, 10) 546 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 547 | names(poker_vector) <- days_vector 548 | names(roulette_vector) <- days_vector 549 | 550 | # Tính tổng lời lãi của việc chơi poker và rulet 551 | total_poker <- 552 | total_roulette <- 553 | 554 | # Kiểm tra xem có đúng bạn kiếm đc nhiều tiền khi chơi poker hơn là khi chơi rulet không 555 | 556 | ``` 557 | 558 | *** =solution 559 | ```{r} 560 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 561 | poker_vector <- c(140, -50, 20, -120, 240) 562 | roulette_vector <- c(-24, -50, 100, -350, 10) 563 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 564 | names(poker_vector) <- days_vector 565 | names(roulette_vector) <- days_vector 566 | 567 | # Tính tổng lời lãi của việc chơi poker và rulet 568 | total_poker <- sum(poker_vector) 569 | total_roulette <- sum(roulette_vector) 570 | 571 | # Kiểm tra xem có đúng bạn kiếm đc nhiều tiền khi chơi poker hơn là khi chơi rulet không 572 | total_poker > total_roulette 573 | ``` 574 | 575 | *** =sct 576 | ```{r} 577 | msg <- "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 578 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 579 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 580 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 581 | 582 | test_object("total_poker", 583 | incorrect_msg = "Nhớ gán tổng của `poker_vector` cho biến `total_poker`. Dùng hàm `sum()`.") 584 | test_object("total_roulette", 585 | incorrect_msg = "Nhớ gán tổng của `roulette_vector` cho biến `total_roulette`. Dùng hàm `sum()`.") 586 | test_output_contains("total_poker > total_roulette", 587 | incorrect_msg = "Bạn đã so sánh đúng chưa? Để kiểm tra xem có phải `total_poker` lớn hơn `total_roulette`, Bạn có thể gõ `total_poker > total_roulette`.") 588 | success_msg("Tốt lắm! Sang bài tập tiếp theo nhé.") 589 | ``` 590 | 591 | 592 | --- type:NormalExercise xp:100 skills:1 key:8d78be44e9 593 | ## Lựa chọn các thành phần trong véc-tơ: Một công việc thú vị 594 | 595 | Dự cảm của bạn có vẻ đúng. Có thể thấy là bạn chơi poker tốt hơn rulet. 596 | 597 | Một hướng điều tra khác là so sánh phong độ của bạn lúc đầu tuần với lúc cuối tuần. Vì mấy ngày cuối tuần đúng là bạn uống hơi nhiều rượu... 598 | 599 | Để trả lời câu hỏi này, bạn chỉ nên tập trung phân tích một phần của `total_vector`. Nói cách khác, chúng ta cần chọn lọc một vài yếu tố của véc-tơ này. Để chọn lọc các yếu tố của 1 véc-tơ (cũng như của một ma trận hoặc một khung dữ liệu). bạn có thể dùng dấu ngoặc vuông. Ở trong dấu ngoặc vuông, bạn chọn ra những yếu tố sẽ được sử dụng. Ví dụ, để chọn yếu tố đầu tiên của véc-tơ này, bạn gõ `poker_vector[1]`. Để chọn yếu tố thứ hai của véc-tơ này, bạn gõ `poker_vector[2]`, v.v... Nhớ là yếu tố đầu tiên được thể hiện bằng số 1, chứ không phải là số 0 như nhiều ngôn ngữ lập trình khác. 600 | 601 | *** =instructions 602 | Gán kết quả chơi poker của thứ Tư cho biến `poker_wednesday`. 603 | 604 | *** =hint 605 | Thứ Tư là yếu tố thứ ba của `poker_vector`, vì vậy bạn gõ `poker_vector[3]`. 606 | 607 | *** =pre_exercise_code 608 | ```{r} 609 | # no pec 610 | ``` 611 | 612 | *** =sample_code 613 | ```{r} 614 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 615 | poker_vector <- c(140, -50, 20, -120, 240) 616 | roulette_vector <- c(-24, -50, 100, -350, 10) 617 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 618 | names(poker_vector) <- days_vector 619 | names(roulette_vector) <- days_vector 620 | 621 | # Thêm một biến mới để thể hiện lựa chọn của bạn 622 | poker_wednesday <- 623 | ``` 624 | 625 | *** =solution 626 | ```{r} 627 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 628 | poker_vector <- c(140, -50, 20, -120, 240) 629 | roulette_vector <- c(-24, -50, 100, -350, 10) 630 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 631 | names(poker_vector) <- days_vector 632 | names(roulette_vector) <- days_vector 633 | 634 | # Thêm một biến mới để thể hiện lựa chọn của bạn 635 | poker_wednesday <- poker_vector[3] 636 | ``` 637 | 638 | *** =sct 639 | ```{r} 640 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 641 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 642 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 643 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 644 | test_object("poker_wednesday", 645 | undefined_msg = "Hãy nhớ gán giá trị cho `poker_wednesday`.", 646 | incorrect_msg = "Hình như `poker_wednesday` đang không chứa giá trị chính xác của `poker_vector`.") 647 | success_msg("Tuyệt lắm! Với R chúng ta cũng có thể cùng một lúc chọn nhiều yếu tố trong một véc-tơ. Bạn sẽ được học cách làm điều này trong bài tập tiếp theo!") 648 | ``` 649 | 650 | 651 | --- type:NormalExercise xp:100 skills:1 key:1351521670 652 | ## Lựa chọn các thành phần trong véc-tơ: Một công việc thú vị (2) 653 | 654 | Hãy thử phân tích kết quả giữa tuần của bạn. 655 | 656 | Bạn có thể đặt dấu ngoặc vuông ở cuối để chọn nhiều yếu tố từ một véc-tơ. Chọn các yếu tố bạn cần dùng và đặt chúng trong dấu ngoặc vuông. Ví dụ: nếu bạn muốn chọn ngày thứ nhất và ngày thứ 5 của tuần, bạn sẽ đặt véc-tơ `c(1, 5)` trong hai dấu ngoặc kép. Ví dụ, câu lệnh dưới đây cho phép bạn lựa chọn yếu tố thứ nhất và thứ 5 của `poker_vector`: 657 | 658 | ``` 659 | poker_vector[c(1, 5)] 660 | ``` 661 | 662 | *** =instructions 663 | Gán kết quả chơi poker của ngày thứ Ba, thứ Tư và thứ 5 cho biến `poker_midweek`. 664 | 665 | *** =hint 666 | Đặt véc-tơ `c(2, 3, 4)` trong hai dấu ngoặc vuông để chọn các véc tơ đúng trong `poker_vector`. 667 | 668 | *** =pre_exercise_code 669 | ```{r} 670 | # no pec 671 | ``` 672 | 673 | *** =sample_code 674 | ```{r} 675 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 676 | poker_vector <- c(140, -50, 20, -120, 240) 677 | roulette_vector <- c(-24, -50, 100, -350, 10) 678 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 679 | names(poker_vector) <- days_vector 680 | names(roulette_vector) <- days_vector 681 | 682 | # Thêm một biến mới để thể hiện lựa chọn của bạn 683 | poker_midweek <- 684 | ``` 685 | 686 | *** =solution 687 | ```{r} 688 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 689 | poker_vector <- c(140, -50, 20, -120, 240) 690 | roulette_vector <- c(-24, -50, 100, -350, 10) 691 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 692 | names(poker_vector) <- days_vector 693 | names(roulette_vector) <- days_vector 694 | 695 | # Thêm một biến mới để thể hiện lựa chọn của bạn 696 | poker_midweek <- poker_vector[c(2, 3, 4)] 697 | ``` 698 | 699 | *** =sct 700 | ```{r} 701 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 702 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 703 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 704 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 705 | test_object("poker_midweek", 706 | incorrect_msg = "Hình như `poker_midweek` không chứa giá trị chính xác của `poker_vector`.Bạn nên đặt `c(2, 3, 4)` trong dấu ngoặc vuông.") 707 | success_msg("Làm tốt lắm! Tiếp tục sang bài tập tiếp theo để tìm hiểu sâu hơn nữa về việc lựa chọn trong véc-tơ!") 708 | ``` 709 | 710 | 711 | --- type:NormalExercise xp:100 skills:1 key:27976b79f4 712 | ## Lựa chọn các thành phần trong véc-tơ: Một công việc thú vị (3) 713 | 714 | Cách chọn nhiều yếu tố trong `poker_vector` với `c(2, 3, 4)` không được thuận tiện cho lắm. Phần lớn các nhà thống kê học đều là những người lười bẩm sinh, nên họ đã phát minh ra một phương pháp đơn giản hơn: `c(2, 3, 4)`, véc-tơ này có thể viết tắt là `2:4`, với cách làm này bạn sẽ tạo ra một véc-tơ gồm toàn số tự nhiên từ 2 đến 4. 715 | 716 | Vậy một cách khác để lấy kết quả của giữa tuần là `poker_vector[2:4]`. Bạn để ý thấy véc-tơ`2:4` được đặt trong dấu ngoặc vuông để chọn các yếu tố từ 2 đến 4. 717 | 718 | *** =instructions 719 | Gán kết quả rulet của thứ Ba đến thứ Sáu cho `roulette_selection_vector`; bạn có thể sử dụng `:` nếu làm thế tiện cho bạn. 720 | 721 | *** =hint 722 | Gán kết quả của việc chọn lọc từ `roulette_vector` cho `roulette_selection_vector` bằng cách đặt `2:5` trong dấu ngoặc vuông. 723 | 724 | *** =sample_code 725 | ```{r} 726 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 727 | poker_vector <- c(140, -50, 20, -120, 240) 728 | roulette_vector <- c(-24, -50, 100, -350, 10) 729 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 730 | names(poker_vector) <- days_vector 731 | names(roulette_vector) <- days_vector 732 | 733 | # Thêm một biến mới để thể hiện lựa chọn của bạn 734 | roulette_selection_vector <- 735 | ``` 736 | 737 | *** =solution 738 | ```{r} 739 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 740 | poker_vector <- c(140, -50, 20, -120, 240) 741 | roulette_vector <- c(-24, -50, 100, -350, 10) 742 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 743 | names(poker_vector) <- days_vector 744 | names(roulette_vector) <- days_vector 745 | 746 | # Thêm một biến mới để thể hiện lựa chọn của bạn 747 | roulette_selection_vector <- roulette_vector[2:5] 748 | ``` 749 | 750 | *** =sct 751 | 752 | ```{r} 753 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 754 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 755 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 756 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 757 | test_object("roulette_selection_vector", 758 | undefined_msg = "Nhớ phải gán giá trị cho biến `roulette_selection_vector`.", 759 | incorrect_msg = "Hình như `roulette_selection_vector` không chứa lựa chọn đúng từ `roulette_vector`. Nhớ dùng đúng số để chọn đúng.") 760 | success_msg("Tuyệt lắm! Dấu hai chấm cực kì hữu dụng và rất thường được sử dụng trong lập trình R, nên bạn hãy nhớ nó nhé. Sang bài tập tiếp theo nào.") 761 | ``` 762 | 763 | 764 | --- type:NormalExercise xp:100 skills:1 key:e6c263ddee 765 | ## Lựa chọn các thành phần trong véc-tơ: Một công việc thú vị (4) 766 | 767 | Một cách khác để hoàn thành bài tập vừa rồi là dùng tên của các yếu tố trong véc-tơ (Monday, Tuesday, ...) thay cho việc dùng số. Ví dụ, câu lệnh 768 | 769 | ``` 770 | poker_vector["Monday"] 771 | ``` 772 | 773 | sẽ lựa chọn yếu tố đầu tiên của `poker_vector` bởi lẽ `"Monday"` là tên của yếu tố đầu tiên. 774 | 775 | Hệt như bài tập với các chữ số vừa rồi, bạn cũng có thể sử dụng tên của các yếu tố để chọn lựa nhiều yếu tố một lúc, ví dụ như: 776 | 777 | ``` 778 | poker_vector[c("Monday","Tuesday")] 779 | ``` 780 | 781 | *** =instructions 782 | - Lựa chọn ba yếu tố đầu tiên của `poker_vector`bằng cách gọi tên của chúng: `"Monday"`, `"Tuesday"` and `"Wednesday"`. Gán kết quả chọn cho `poker_start`. 783 | - Tính trung bình các giá trị trong `poker_start`với hàm [`mean()`](http://www.rdocumentation.org/packages/base/functions/mean). Sau đó hiển thị kết quả để kiểm tra độ chính xác. 784 | 785 | *** =hint 786 | - Bạn có thể đặt véc-tơ `c("Monday", "Tuesday", "Wednesday")` trong dấu ngoặc vuông để chọn lựa từ `poker_vector`. 787 | - Có thể dùng hàm `mean(poker_start)` để tính giá trị trung bình của `poker_start`. Bạn không cần trung bình của tất cả các yếu tố trong poker, mà chỉ cần của ba ngày đầu tiên. 788 | 789 | *** =pre_exercise_code 790 | ```{r} 791 | # no pec 792 | ``` 793 | 794 | *** =sample_code 795 | ```{r} 796 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 797 | poker_vector <- c(140, -50, 20, -120, 240) 798 | roulette_vector <- c(-24, -50, 100, -350, 10) 799 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 800 | names(poker_vector) <- days_vector 801 | names(roulette_vector) <- days_vector 802 | 803 | # Chọn kết quả chơi poker của thứ Hai, thứ Ba và thứ Tư 804 | poker_start <- 805 | 806 | # Tính trung bình của các yếu tố trong poker_start 807 | 808 | ``` 809 | 810 | *** =solution 811 | ```{r} 812 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 813 | poker_vector <- c(140, -50, 20, -120, 240) 814 | roulette_vector <- c(-24, -50, 100, -350, 10) 815 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 816 | names(poker_vector) <- days_vector 817 | names(roulette_vector) <- days_vector 818 | 819 | # Chọn kết quả chơi poker của thứ Hai, thứ Ba và thứ Tư 820 | poker_start <- poker_vector[c("Monday", "Tuesday", "Wednesday")] 821 | 822 | # Tính trung bình của các yếu tố trong poker_start 823 | mean(poker_start) 824 | ``` 825 | 826 | *** =sct 827 | ```{r} 828 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 829 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 830 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 831 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 832 | test_object("poker_start", 833 | incorrect_msg = "Có vẻ như `poker_start` không chứa ba giá trị đầu tiên của `poker_vector`. Để làm điều này bạn cho các giá trị `c(\"Monday\", \"Tuesday\", \"Wednesday\")` vào trong dấu ngoặc vuông.") 834 | test_output_contains("mean(poker_start)", incorrect_msg = "Bạn đã tính và hiển thị ra màn hình console đúng giá trị trung bình của `poker_start` chưa? Dùng hàm `mean(poker_start)`.") 835 | success_msg("Giỏi lắm! Ngoài việc chia nhỏ véc-tơ theo thứ hoặc theo tên, bạn cũng có thể làm thế nhờ việc so sánh. Bài tập tiếp theo sẽ hướng dẫn bạn cách làm này!"); 836 | ``` 837 | 838 | 839 | --- type:NormalExercise xp:100 skills:1 key:f0f619c901 840 | ## Lựa chọn bằng cách so sánh - Bước 1 841 | 842 | Bằng cách sử dụng các dấu so sánh, chúng ta có thể trả lời câu hỏi ở bài tập trước một cách chủ động và đơn giản hơn. 843 | 844 | Các dấu so sánh dạng lôgic được sử dụng trong R: 845 | 846 | - `<` nhỏ hơn 847 | - `>` lớn hơn 848 | - `<=` nhỏ hơn hoặc bằng 849 | - `>=` lớn hơn hoặc bằng 850 | - `==` bằng nhau 851 | - `!=` không bằng nhau 852 | 853 | Trong chương trước, bạn đã học là `6 > 5` trả cho bạn kết quả `TRUE`. Cái hay của R là bạn cũng có thể sử dụng những dấu so sánh trên cho véc-tơ. Ví dụ: 854 | 855 | ``` 856 | > c(4, 5, 6) > 5 857 | [1] FALSE FALSE TRUE 858 | ``` 859 | 860 | Lệnh này kiểm tra tất cả các yếu tố trong véc-tơ theo dấu so sánh và trả về giá trị `TRUE` hoặc `FALSE`. 861 | 862 | *** =instructions 863 | - Kiểm tra xem những giá trị nào trong `poker_vector` là giá trị dương (VD: 0) và gán kết quả này cho `selection_vector`. 864 | - Hiển thị `selection_vector` để kiểm tra kết quả. Kết quả này chỉ cho bạn thấy bạn đã thắng độ (`TRUE`) hay thua độ (`FALSE`) mỗi ngày. 865 | 866 | *** =hint 867 | Để kiểm tra xem bạn thắng poker vào những ngày nào. R sẽ kiểm tra tất cả các yếu tố trong `poker_vector` có lớn hơn 0 không. Để trả lời câu hỏi này, bạn viết lệnh `some_vector > 0` 868 | 869 | *** =pre_exercise_code 870 | ```{r} 871 | # no pec 872 | ``` 873 | 874 | *** =sample_code 875 | ```{r} 876 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 877 | poker_vector <- c(140, -50, 20, -120, 240) 878 | roulette_vector <- c(-24, -50, 100, -350, 10) 879 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 880 | names(poker_vector) <- days_vector 881 | names(roulette_vector) <- days_vector 882 | 883 | # Bạn chơi poker thắng tiền vào những ngày nào? 884 | selection_vector <- 885 | 886 | # Hiển thị kết quả của selection_vector 887 | 888 | ``` 889 | 890 | *** =solution 891 | ```{r} 892 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 893 | poker_vector <- c(140, -50, 20, -120, 240) 894 | roulette_vector <- c(-24, -50, 100, -350, 10) 895 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 896 | names(poker_vector) <- days_vector 897 | names(roulette_vector) <- days_vector 898 | 899 | # Bạn chơi poker thắng tiền vào những ngày nào? 900 | selection_vector <- poker_vector > 0 901 | 902 | # Hiển thị kết quả của selection_vector 903 | selection_vector 904 | ``` 905 | 906 | *** =sct 907 | ```{r} 908 | msg <- "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 909 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 910 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 911 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 912 | 913 | test_object("selection_vector", incorrect_msg = "Có vẻ như `selection_vector` không thể hiện kết quả đúng. Hãy nhớ rằng R kiểm tra từng yếu tố của véc-tơ.") 914 | test_output_contains("selection_vector", incorrect_msg = "Đừng quên hiển thị kết quả của`selection_vector` bằng cách gõ tên biến trên một dòng mới.") 915 | success_msg("Tuyệt vời!") 916 | ``` 917 | 918 | 919 | --- type:NormalExercise xp:100 skills:1 key:2754fc5cd4 920 | ## Lựa chọn bằng cách so sánh - Bước 2 921 | 922 | Sử dụng phép so sánh sẽ giúp bạn dễ dàng trong việc phân tích số liệu hơn. Thay vì phải chọn tập con của giá trị ngày để điều tra như trước, bạn chỉ cần yêu cầu R trả lại kết quả của những ngày bạn kiếm được tiền nhờ việc chơi poker. 923 | 924 | Trong những bài tập trước đây, bạn sử dụng `selection_vector <- poker_vector > 0` để tìm những ngày bạn kiếm được tiền nhờ việc chơi poker. Bây giờ bạn không chỉ muốn biết ngày nào bạn thắng, và còn muốn biết những ngày đó bạn thắng bao nhiêu tiền. 925 | 926 | Bạn có thể chọn những yếu tố bạn muốn chọn bằng cách đặt `selection_vector` vào trong dấu ngoặc vuông ngay sau `poker_vector`: 927 | 928 | ``` 929 | poker_vector[selection_vector] 930 | ``` 931 | 932 | R sẽ hiểu khi bạn đặt một véc-tơ lôgic trong ngoặc vuông và sẽ chỉ chọn những yếu tố được trả về giá trị `TRUE` trong `selection_vector`. 933 | 934 | *** =instructions 935 | Đặt `selection_vector` trong dấu ngoặc vuông để gán giá trị bạn thắng theo ngày thắng cho biến `poker_winning_days`. 936 | 937 | *** =hint 938 | Dùng `poker_vector[selection_vector]` để chọn biến trong `poker_vector`, và gán kết quả cho `poker_winning_days`. 939 | 940 | *** =pre_exercise_code 941 | ```{r} 942 | # no pec 943 | ``` 944 | 945 | *** =sample_code 946 | ```{r} 947 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 948 | poker_vector <- c(140, -50, 20, -120, 240) 949 | roulette_vector <- c(-24, -50, 100, -350, 10) 950 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 951 | names(poker_vector) <- days_vector 952 | names(roulette_vector) <- days_vector 953 | 954 | # Bạn chơi poker thắng tiền vào những ngày nào? 955 | selection_vector <- poker_vector > 0 956 | 957 | # Chọn những ngày đó trong poker_vector 958 | poker_winning_days <- 959 | ``` 960 | 961 | *** =solution 962 | ```{r} 963 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 964 | poker_vector <- c(140, -50, 20, -120, 240) 965 | roulette_vector <- c(-24, -50, 100, -350, 10) 966 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 967 | names(poker_vector) <- days_vector 968 | names(roulette_vector) <- days_vector 969 | 970 | # Bạn chơi poker thắng tiền vào những ngày nào? 971 | selection_vector <- poker_vector > 0 972 | 973 | # Chọn những ngày đó trong poker_vector 974 | poker_winning_days <- poker_vector[selection_vector] 975 | ``` 976 | 977 | *** =sct 978 | ```{r} 979 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 980 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 981 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 982 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 983 | test_object("selection_vector", incorrect_msg = "Đừng sửa cách tính của `selection_vector`.") 984 | test_object("poker_winning_days", 985 | incorrect_msg = "Có vẻ như `poker_winning_days` không cho kết quả chính xác. Dùng `poker_vector[selection_vector]`.") 986 | success_msg("Tốt lắm! Sang bài tập tiếp theo nhé.") 987 | ``` 988 | 989 | 990 | --- type:NormalExercise xp:100 skills:1 key:59e8dcbbd5 991 | ## Điều kiện lọc nâng cao 992 | 993 | Tương tự như khi phân tích trò chơi poker, bạn cũng muốn biết ngày nào bạn thắng độ rulet. 994 | 995 | *** =instructions 996 | - Tạo biến `selection_vector` để xem bạn có thắng độ không và nếu có thì vào những ngày nào. 997 | - Gán các giá trị tiền bạn kiếm được trong những ngày bạn thắng độ với trò rulet cho véc-tơ `roulette_winning_days`. Véc-tơ này sẽ chứa tiền thắng độ của `roulette_vector`. 998 | 999 | *** =hint 1000 | Sau khi bạn đã tính đúng giá trị của `selection_vector`, bạn có thể dùng `roulette_vector[selection_vector]` để chọn giá trị dương từ `roulette_vector`. 1001 | 1002 | *** =pre_exercise_code 1003 | ```{r} 1004 | # no pec 1005 | ``` 1006 | 1007 | *** =sample_code 1008 | ```{r} 1009 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 1010 | poker_vector <- c(140, -50, 20, -120, 240) 1011 | roulette_vector <- c(-24, -50, 100, -350, 10) 1012 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 1013 | names(poker_vector) <- days_vector 1014 | names(roulette_vector) <- days_vector 1015 | 1016 | # Bạn chơi rulet thắng tiền vào những ngày nào? 1017 | selection_vector <- 1018 | 1019 | # Chọn những ngày đó từ roulette_vector 1020 | roulette_winning_days <- 1021 | ``` 1022 | 1023 | *** =solution 1024 | ```{r} 1025 | # Tổng lời lãi của việc chơi poker và rulet từ thứ Hai đến thứ Sáu: 1026 | poker_vector <- c(140, -50, 20, -120, 240) 1027 | roulette_vector <- c(-24, -50, 100, -350, 10) 1028 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 1029 | names(poker_vector) <- days_vector 1030 | names(roulette_vector) <- days_vector 1031 | 1032 | # Bạn chơi rulet thắng tiền vào những ngày nào? 1033 | selection_vector <- roulette_vector > 0 1034 | 1035 | # Chọn những ngày đó từ roulette_vector 1036 | roulette_winning_days <- roulette_vector[selection_vector] 1037 | ``` 1038 | 1039 | *** =sct 1040 | ```{r} 1041 | msg = "Đừng sửa gì trong phần định nghĩa và đặt tên của biến `poker_vector` và `roulette_vector`." 1042 | test_object("days_vector", undefined_msg = msg, incorrect_msg = msg) 1043 | test_object("poker_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 1044 | test_object("roulette_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 1045 | test_object("selection_vector", 1046 | incorrect_msg = "Có vẻ như `selection_vector` không chứa giá trị chính xác. Sử dụng `roulette_vector > 0`.") 1047 | test_object("roulette_winning_days", 1048 | incorrect_msg = "Có vẻ như `roulette_winning_days` không chứa giá trị chính xác. Sử dụng `roulette_vector[selection_vector]`.") 1049 | 1050 | success_msg("Tuyệt vời! Chương về véc-tơ đã kết thúc ở tại đây. Ở chương tiếp theo, bạn sẽ được học phiên bản 2D của véc-tơ: Ma trận.") 1051 | ``` 1052 | 1053 | 1054 | 1055 | --------------------------------------------------------------------------------