├── requirements.r ├── img ├── .DS_Store └── author_image.png ├── datasets ├── .DS_Store ├── planets.RData ├── shining_list.RData ├── all_wars_matrix.RData ├── chapter6.R ├── chapter5.R └── chapter3.R ├── .gitignore ├── README.md ├── convert.R ├── course.yml ├── chapter6.Rmd ├── chapter1.Rmd ├── chapter4.Rmd ├── chapter5.Rmd ├── chapter3.Rmd └── chapter2.Rmd /requirements.r: -------------------------------------------------------------------------------- 1 | # no packages required 2 | -------------------------------------------------------------------------------- /img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-chinese/master/img/.DS_Store -------------------------------------------------------------------------------- /datasets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-chinese/master/datasets/.DS_Store -------------------------------------------------------------------------------- /img/author_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-chinese/master/img/author_image.png -------------------------------------------------------------------------------- /datasets/planets.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-chinese/master/datasets/planets.RData -------------------------------------------------------------------------------- /datasets/shining_list.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-chinese/master/datasets/shining_list.RData -------------------------------------------------------------------------------- /datasets/all_wars_matrix.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/community-courses-introduction-to-r-chinese/master/datasets/all_wars_matrix.RData -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.Rmd 3 | !*.yml 4 | !img/ 5 | !img/* 6 | !README.md 7 | !.gitignore 8 | .Rproj.user 9 | !datasets/ 10 | !datasets/* 11 | !convert.R 12 | !requirements.r 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction to R - Chinese 2 | 3 | This repository contains the source files for the Chinese version of the introduction to R course. 4 | 5 | This repository is linked to DataCamp Teach: every change that is pushed to the GitHub repository, will be reflected on DataCamp automatically. 6 | 7 | URL of the course: https://www.datacamp.com/courses/introduction-to-r-chinese 8 | -------------------------------------------------------------------------------- /convert.R: -------------------------------------------------------------------------------- 1 | # This little script converts \u____ encodings to &#____; encodings 2 | file <- "chapter6.Rmd" 3 | 4 | library(stringr) 5 | file_string <- paste(readLines(file), collapse = "\n") 6 | unicodes <- unique(str_extract_all(file_string, "\\\\u[0-9a-fA-F]{4}"))[[1]] 7 | translations <- paste0("&#", strtoi(gsub("\\\\u", "", unicodes) , base = 16L), ";") 8 | names(translations) <- paste0("\\", unicodes) 9 | write(str_replace_all(file_string, translations), file = file) 10 | -------------------------------------------------------------------------------- /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") -------------------------------------------------------------------------------- /datasets/chapter3.R: -------------------------------------------------------------------------------- 1 | # Construct matrix 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 | # Construct matrix2 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 | # Combine both Star Wars trilogies in one matrix 13 | all_wars_matrix <- rbind(star_wars_matrix, star_wars_matrix2) 14 | 15 | # remove all except 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: R 語言導論 2 | author_field: Tony Yao-Jen Kuo 3 | description: "我們將在 R 語言導論學習這個熱門的開源軟體,包含因素向量、清單與資料框等資料類別。 4 | 透過這門課的內容我們就可以著手對資料做分析。 5 | 目前 R 語言在全球已經有超過兩百萬個使用者,且人數以年增率 40% 高速成長中。 6 | 隨著日益增多的學術及商業組織在日常作業中使用 R 做資料分析,它也逐漸成為統計與資料科學的主流程式語言。 7 | 即刻開始學習免費的線上課程,體驗 R 語言的美妙之處!" 8 | author_bio: "郭耀仁畢業於臺灣大學商學研究所碩士班,是資料科學與推廣教育的愛好者。目前是新創公司 Kyosei 的共同創辦人;同時亦是臺大系統訓練班的講師成員,推廣資料科學,R 語言與 Python, 9 | 班上熱心的學員是協助校正中文課程的得力助手。在 Kyosei 之前是 Coupang 的資料分析師與 SAS 分析顧問。 10 | 閒暇時熱愛長跑與乒乓球,參加 2016 年波士頓馬拉松時初次拜訪 DataCamp,與我們一同討論課程的中文化與資料科學的推廣。 11 |
12 |
13 | Yao-Jen is enthusiastic about data science and education. 14 | He is now one of the co-founders at Kyosei, a startup focusing on light-weight data science solutions. 15 | He lectures on \"Data Science and R/Python\" at System Training Program of NTU. 16 | Active students in class helps him elaborate the localized courses. 17 | Prior to founding Kyosei, he was a senior data analyst at Coupang and an analytical consultant at SAS Software. 18 | He holds a M.B.A. at NTU, however, his career so far is quite different from most of his peers. 19 | In his spare time, he enjoys Marathons and ping-pong. In fact, the first time we met him was the 2016 Boston Marathon. 20 | He came to our office after the race and discussed localization of our courses." 21 | from: 'r-base-prod:27' 22 | -------------------------------------------------------------------------------- /chapter6.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : 第六章 3 | title : 清單 4 | description : 清單與向量最大的不同是清單可以儲存不同類型的資料格式,就像我們的工作項目清單一樣,本章節我們將學會如何建立、命名以及選擇清單中的元素。 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:b02020c3b8ccf1d6ea63f5801cc80ae49bf49b15 7 | ## 為什麼會需要清單? 8 | 9 | 恭喜你,課程進行到這裡你已經對以下的資料類別非常熟悉: 10 | 11 | - **向量**(單一維度的陣列):可以包含數值、字串或邏輯值,向量中的元素均屬於同一種資料類型。 12 | - **矩陣**(兩個維度的陣列):可以包含數值、字串或邏輯值,矩陣中的元素均屬於同一種資料類型。 13 | - **資料框**(兩個維度的物件):可以包含數值、字串或邏輯值,在同一個欄位中所有的元素均屬於同一種資料類型,但不同的欄位可以各自屬於不同的資料類型。 14 | 15 | 這樣的整理對 R 的新手很貼心對吧? ;-) 16 | 17 | *** =instructions 18 | 按下 Submit Answer 開始學習清單吧! 19 | 20 | *** =hint 21 | 按下 Submit Answer 按鈕。 22 | 23 | *** =pre_exercise_code 24 | ```{r} 25 | # no pec 26 | ``` 27 | 28 | *** =sample_code 29 | ```{r} 30 | # 按下 Submit Answer 按鈕 31 | ``` 32 | 33 | *** =solution 34 | ```{r} 35 | # 按下 Submit Answer 按鈕 36 | ``` 37 | 38 | *** =sct 39 | ```{r} 40 | success_msg("準備好,前進下一個練習!") 41 | ``` 42 | 43 | 44 | --- type:NormalExercise xp:100 skills:1 key:d6f368841ef8395b0cf19fbaa2e23c7ce2c8672d 45 | ## 為什麼會需要清單?(2) 46 | 47 | **清單**在 R 中跟你的工作項目或學習項目很像,這些要完成的項目長度、特性或者活動類型都不一樣。 48 | 49 | 清單可以蒐集多樣性的物件,包含矩陣、向量、資料框甚至清單,這些物件甚至不需要跟彼此相關。 50 | 51 | 你可以將清單視為一種超級資料類型,基本上你可以將任何資訊都儲存在清單中! 52 | 53 | *** =instructions 54 | 按下 Submit Answer 開始第一個清單的練習。 55 | 56 | *** =hint 57 | 按下 Submit Answer 開始第一個清單的練習。 58 | 59 | *** =pre_exercise_code 60 | ```{r} 61 | # no pec 62 | ``` 63 | 64 | *** =sample_code 65 | ```{r} 66 | # 按下 Submit Answer 開始第一個清單的練習 67 | ``` 68 | 69 | *** =solution 70 | ```{r} 71 | # 按下 Submit Answer 開始第一個清單的練習 72 | ``` 73 | 74 | *** =sct 75 | ```{r} 76 | success_msg("酷斃了,把袖子捲起來幹活吧!") 77 | ``` 78 | 79 | 80 | --- type:NormalExercise xp:100 skills:1 key:3c886887d481e450e4d55fdc6504f4b9cd99083e 81 | ## 建立一個清單 82 | 83 | 你需要使用[`list()`](http://www.rdocumentation.org/packages/base/functions/list)函數建立一個清單: 84 | 85 | ``` 86 | my_list <- list(comp1, comp2 ...) 87 | ``` 88 | 89 | list 函數的參數即為清單中的物件,這些物件可以是矩陣、向量或者其他清單。 90 | 91 | *** =instructions 92 | 宣告一個清單,指派為 `my_list` 包含變數 `my_vector` 、 `my_matrix` 與 `my_df` 。 93 | 94 | *** =hint 95 | 使用[`list()`](http://www.rdocumentation.org/packages/base/functions/list)函數並以逗號區隔 `my_vector` 、 `my_matrix` 與 `my_df` 作為不同參數。 96 | 97 | *** =pre_exercise_code 98 | ```{r} 99 | # no pec 100 | ``` 101 | 102 | *** =sample_code 103 | ```{r} 104 | # 數值 1 到 10 的向量 105 | my_vector <- 1:10 106 | 107 | # 數值 1 到 9 的矩陣 108 | my_matrix <- matrix(1:9, ncol = 3) 109 | 110 | # 内建資料框 mtcars 的前 10 列 111 | my_df <- mtcars[1:10,] 112 | 113 | # 宣告清單 114 | my_list <- 115 | ``` 116 | 117 | *** =solution 118 | ```{r} 119 | # 數值 1 到 10 的向量 120 | my_vector <- 1:10 121 | 122 | # 數值 1 到 9 的矩陣 123 | my_matrix <- matrix(1:9, ncol = 3) 124 | 125 | # 内建資料框 mtcars 的前 10 列 126 | my_df <- mtcars[1:10,] 127 | 128 | # 宣告清單 129 | my_list <- list(my_vector, my_matrix, my_df) 130 | ``` 131 | 132 | *** =sct 133 | ```{r} 134 | msg = "不需要移除或更改變數 `my_vector` 、 `my_matrix` 或 `my_df` 的內容。" 135 | test_object("my_vector", undefined_msg = msg, incorrect_msg = msg) 136 | test_object("my_matrix", undefined_msg = msg, incorrect_msg = msg) 137 | test_object("my_df", undefined_msg = msg, incorrect_msg = msg) 138 | test_object("my_list", 139 | incorrect_msg = "看起來 `my_list` 沒有包含正確的元素,確認是否有將 `my_vector` 、 `my_matrix` 與 `my_df` 依序作為 `list()` 函數的引數並以逗號分隔。") 140 | success_msg("太棒了,前進下一個練習!") 141 | ``` 142 | 143 | 144 | --- type:NormalExercise xp:100 skills:1 key:60372e4e466c431316ece6222f3385ef239dce7e 145 | ## 建立一個有項目名稱的清單 146 | 147 | 太棒了,你學得正順呢! 148 | 149 | 為了防止你忘記清單中的項目,你應該要幫這些項目命名: 150 | 151 | ``` 152 | my_list <- list(name1 = your_comp1, 153 | name2 = your_comp2) 154 | ``` 155 | 156 | 上述程式中 `name1` 、 `name2` 分別對清單中的每個項目命名,如果希望在建立清單後才命名,我們可以在建立清單後再使用 `names()` 函數,例如下面這兩行程式,執行後的結果與上述程式完全相同: 157 | 158 | ``` 159 | my_list <- list(your_comp1, your_comp2) 160 | names(my_list) <- c("name1", "name2") 161 | ``` 162 | 163 | *** =instructions 164 | - 更改編輯區前一個練習的程式,將 `my_vector` 命名為 `vec`、將 `my_matrix` 命名為 `mat` 並將 `my_df` 命名為 `df`。 165 | - 將 `my_list` 印出檢視。 166 | 167 | *** =hint 168 | 第一個指派清單項目名稱的方法是最簡單的: 169 | ``` 170 | my_list <- list(vec = my_vector) 171 | ``` 172 | 依樣畫葫蘆加入另外兩個元素。 173 | 174 | *** =pre_exercise_code 175 | ```{r} 176 | # no pec 177 | ``` 178 | 179 | *** =sample_code 180 | ```{r} 181 | # 數值 1 到 10 的向量 182 | my_vector <- 1:10 183 | 184 | # 數值 1 到 9 的矩陣 185 | my_matrix <- matrix(1:9, ncol = 3) 186 | 187 | # 内建資料框 mtcars 的前 10 列 188 | my_df <- mtcars[1:10,] 189 | 190 | # 使用 list() 建立清單 191 | my_list <- list(my_vector, my_matrix, my_df) 192 | 193 | # 印出 my_list 194 | 195 | ``` 196 | 197 | *** =solution 198 | ```{r} 199 | # 數值 1 到 10 的向量 200 | my_vector <- 1:10 201 | 202 | # 數值 1 到 9 的矩陣 203 | my_matrix <- matrix(1:9, ncol = 3) 204 | 205 | # 内建資料框 mtcars 的前 10 列 206 | my_df <- mtcars[1:10,] 207 | 208 | # 使用 list() 建立清單 209 | my_list <- list(vec = my_vector, mat = my_matrix, df = my_df) 210 | 211 | # 印出 my_list 212 | my_list 213 | ``` 214 | 215 | *** =sct 216 | ```{r} 217 | msg = "不需要移除或更改變數 `my_vector` 、 `my_matrix` 或 `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 = "看起來 `my_list` 並沒有包含正確的元素。") 223 | test_object("my_list", eq_condition = "equal", 224 | incorrect_msg = "看起來 `my_list` 並沒有包含正確的元素。確認是否分別使用了 `vec` 、 `mat` 與 `df` 作命名,如果還是不清楚的話可以看看提示。"); 225 | test_output_contains("my_list", incorrect_msg = "別忘記了將 `my_list` 印出,在編輯區多加一行程式 `my_list` 就可以作到。") 226 | success_msg("太棒了,你現在不只知道了如何建立清單,你還學會了實用技巧為清單的元素命名,前進下一個練習!") 227 | ``` 228 | 229 | 230 | --- type:NormalExercise xp:100 skills:1 key:cf2bc8104cc549cdd4eab9773bfe0d234effa9d5 231 | ## 建立一個有項目名稱的清單(2) 232 | 233 | 別忘了你是盧卡斯影業的員工,身為一個超級電影迷,你決定把好看的電影資訊儲存在清單中。 234 | 235 | 讓我們建立一個電影清單 "The Shining",變數 `mov` 、 `act` 與 `rev` 已經預先建立在工作空間,你可以在 R Console 中檢視這些變數。 236 | 237 | *** =instructions 238 | 完成編輯區的程式建立 `shining_list`,這個清單包含了 3 個元素: 239 | 240 | - 電影名稱:電影名稱是一個字串(儲存於 `mov` 中) 241 | - 演員:主要演員姓名向量(儲存於 `act` 中) 242 | - 評論:電影評論資訊的資料框(儲存於 `rev` 中) 243 | 244 | 不要忘了為清單中的項目命名(依序為 moviename、actors 與 reviews)。 245 | 246 | *** =hint 247 | `shining_list <- list(moviename = mov)` 只包含了部份的解答,你還需要在清單中加入 `act` 與 `rev` 並給予適當命名。 248 | 249 | *** =pre_exercise_code 250 | ```{r} 251 | mov <- "The Shining" 252 | act <- c("Jack Nicholson","Shelley Duvall","Danny Lloyd","Scatman Crothers","Barry Nelson") 253 | sources <- c("IMDb1","IMDb2","IMDb3") 254 | comments <- c("Best Horror Film I Have Ever Seen","A truly brilliant and scary film from Stanley Kubrick","A masterpiece of psychological horror") 255 | scores <- c(4.5,4,5) 256 | rev <- data.frame(scores, sources, comments) 257 | rm(scores, sources, comments) 258 | ``` 259 | 260 | *** =sample_code 261 | ```{r} 262 | # 變數 mov、act 與 rev 已經預先載入 263 | 264 | # 完成這段程式建立 shining_list 265 | shining_list <- list(moviename = mov) 266 | ``` 267 | 268 | *** =solution 269 | ```{r} 270 | # 變數 mov、act 與 rev 已經預先載入 271 | 272 | # 完成這段程式建立 shining_list 273 | shining_list <- list(moviename = mov, actors = act, reviews = rev) 274 | ``` 275 | 276 | *** =sct 277 | ```{r} 278 | msg = "不需要移除或更改預先建立好的這些變數。" 279 | lapply(c("mov", "rev", "act"), test_object, undefined_msg = msg, incorrect_msg = msg) 280 | test_object("shining_list", 281 | incorrect_msg = "看起來 `shining_list` 並沒有包含正確的元素,第一個元素應為 `mov` 、 第二個元素應為 `act` 而第三個為 `rev`。") 282 | test_object("shining_list", eq_condition = "equal", 283 | incorrect_msg = "看起來 `shining_list` 並沒有為元素作正確的命名,第一個元素應命名為 `moviename` ,第二個元素命名為 `actors` 而第三個元素命名為 `reviews`。"); 284 | success_msg("太棒了,你現在知道如何建立並為清單命名,如同前面的章節,我們來看看如何從清單中選擇元素,前進下一個練習!") 285 | ``` 286 | 287 | 288 | --- type:NormalExercise xp:100 skills:1 key:5bbf2c7bd99765106af3ccb1ee48649d763161ef 289 | ## 從清單中選擇元素 290 | 291 | 清單常包含多種的元素與項目。因此,從清單中選取單一元素、多個元素或部分項目,並不是件非常直觀的事。 292 | 293 | 利用索引值選取是一種方式,例如輸入下列程式可取出 `shining_list` 中的第一個項目: 294 | 295 | ``` 296 | shining_list[[1]] 297 | ``` 298 | 299 | 可別跟用單一個中括號 `[ ]` 從向量中選擇元素搞混了,你可以在 R Console 中快速輸入並檢視結果! 300 | 301 | 你也可以使用項目的名稱選擇,使用 `[[ ]]` 或 `$` 都可以達成同樣目的: 302 | 303 | ``` 304 | shining_list[["reviews"]] 305 | shining_list$reviews 306 | ``` 307 | 308 | 除了選出清單中的項目以外,你也常需要選出特定元素,例如 `shining_list[[2]][1]` 可以選出第二個項目 `actors` (`shining_list[[2]]`)中的第一個元素(`[1]`),R Console 將會回傳 Jack Nicholson。 309 | 310 | *** =instructions 311 | - 從 `shining_list` 中選出演員向量,並將該向量印出。 312 | - 從前述的向量中選出第二個元素,並將該向量印出。 313 | 314 | *** =hint 315 | - 使用 `$actors` 可以從清單中選出演員的向量。 316 | - 利用 `shining_list$actors[3]` 可以從前述向量中選出第三個元素,如果你想改選擇第二個元素應該要修改哪個部分? 317 | 318 | *** =pre_exercise_code 319 | ```{r} 320 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/shining_list.RData")) 321 | ``` 322 | 323 | *** =sample_code 324 | ```{r} 325 | # shining_list 已經預先載入 326 | 327 | # 將儲存演員資訊的向量印出 328 | 329 | 330 | # 查詢第二位演員的名字 331 | 332 | ``` 333 | 334 | *** =solution 335 | ```{r} 336 | # shining_list 已經預先載入 337 | 338 | # 將儲存演員資訊的向量印出 339 | shining_list$actors 340 | 341 | # 查詢第二位演員的名字 342 | shining_list$actors[2] 343 | ``` 344 | 345 | *** =sct 346 | ```{r} 347 | msg <- "不需要移除或更改已預先載入的 `shining_list` 的宣告。" 348 | test_object("shining_list", undefined_msg = msg, incorrect_msg = msg) 349 | test_output_contains("shining_list$actors", incorrect_msg = "確認是否有使用 `shining_list$actors` 將清單中的演員向量印出?") 350 | test_output_contains("shining_list$actors[2]", incorrect_msg = "在 `shining_list$actors` 後面加上 `[2]` 可以選出第二個元素。") 351 | success_msg("太棒了,從清單中選擇元素是否相當容易?繼續前進下一個練習!") 352 | ``` 353 | 354 | 355 | --- type:NormalExercise xp:100 skills:1 key:4cec127e7811993251c89ede9a6e976958f66be5 356 | ## 在清單中增加更多電影資訊 357 | 358 | 你向幾位電影愛好者分享了你的清單,其中一位資深成員 M. McDowell 點出清單中遺漏了上映年份這個重要的資訊,基於對自我的高標準要求,你決定要把這個遺漏的資訊補入清單中。 359 | 360 | 使用[`c()`](http://www.rdocumentation.org/packages/base/functions/c)函數可以為清單增加資訊: 361 | 362 | ``` 363 | ext_list <- c(my_list , my_val) 364 | ``` 365 | 366 | 這段程式會為原本的清單 `my_list` 加入 `my_val`。如果你希望為新的項目命名,也可以用與先前類似的方法做到: 367 | 368 | ``` 369 | ext_list <- c(my_list, my_name = my_val) 370 | ``` 371 | 372 | *** =instructions 373 | - 完成以下的程式把 `year = 1980`加入 `shining_list` 中,並將結果指派給 `shining_list_full`。 374 | - 最後,利用[`str()`](http://www.rdocumentation.org/packages/utils/functions/str)函數觀察 `shining_list_full` 的結構。 375 | 376 | *** =hint 377 | 看一下範例程式: 378 | ``` 379 | shining_list <- c(shining_list, ...) 380 | ``` 381 | 你要在 ... 的部分加入一些程式。 382 | 383 | *** =pre_exercise_code 384 | ```{r, eval = FALSE} 385 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/shining_list.RData")) 386 | ``` 387 | 388 | *** =sample_code 389 | 390 | ```{r} 391 | # 包含電影名稱、演員與評論的 shining_list 已經預先載入 392 | 393 | # 利用 c() 把上映年份加入 shining_list 394 | shining_list_full <- 395 | 396 | # 看看 shining_list_full 的結構 397 | 398 | ``` 399 | 400 | *** =solution 401 | 402 | ```{r} 403 | # 包含電影名稱、演員與評論的 shining_list 已經預先載入 404 | 405 | # 利用 c() 把上映年份加入 shining_list 406 | shining_list_full <- c(shining_list, year = 1980) 407 | 408 | # 看看 shining_list_full 的結構 409 | str(shining_list_full) 410 | ``` 411 | 412 | *** =sct 413 | ```{r} 414 | msg = "不需要移除或更改已預先載入的 `shining_list`。" 415 | test_object("shining_list", undefined_msg = msg, incorrect_msg = msg) 416 | test_object("shining_list_full", eq_condition = "equal", 417 | incorrect_msg = paste("確認是否有為 `shining_list` 增加一個元素 `year` =1980,", 418 | "記得使用 `c(shining_list, year = 1980)`")) 419 | test_function("str", "object", incorrect_msg = "不要忘了利用 `str()` 將 `shining_list_full` 的結構印出。") 420 | success_msg("太棒了,你已經完成清單章節的最後一個練習,你現在對 R 程式語言有了清楚的認知,但還有很多值得學習,請繼續修習其他的 DataCamp 課程並成為一個資料科學家!") 421 | ``` 422 | 423 | 424 | -------------------------------------------------------------------------------- /chapter1.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : 第一章 3 | title : 基本介紹 4 | description : "本章節是我們與 R 的第一次接觸,我們將學習如何使用 R 做數學運算以及如何宣告變數,也會學習 R 的基本資料類別,讓我們趕快開始吧!" 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:dd8bfba816aff286aa9d14ea7f632bec1e58a1e6 7 | ## 熟悉環境 8 | 9 | 你要在右邊的編輯區輸入程式來完成練習,當你按下 Submit Answer 的按鈕後,每一行程式都會被執行,R 將會回傳正確或錯誤的訊息,程式的輸出結果會呈現在右下角的 R Console 視窗中。 10 | 11 | R 就跟 Twitter 一樣使用 `#` 來加入程式的註解,讓你與其他人可以更快了解這段程式的用途!註解不會被執行,故不影響結果,例如:在右方編輯區的第一行 _# 計算 3 + 4_ 就是註解。 12 | 13 | 若想測試語法是否正確,可以直接在 R Console 中輸入程式並按 Enter 執行。 14 | 15 | *** =instructions 16 | - 在右邊的編輯區已經有了一些範例,你看得出來哪些是會被執行的程式,哪些是不會被執行的註解嗎? 17 | - 加入一行程式計算 6 加 12 ,然後按下 Submit Answer。 18 | 19 | *** =hint 20 | 參考一下範例,加入一行程式計算 6 加 12。 21 | 22 | *** =pre_exercise_code 23 | ```{r} 24 | # no pec 25 | ``` 26 | 27 | *** =sample_code 28 | ```{r} 29 | # 計算 3 + 4 30 | 3 + 4 31 | 32 | # 計算 6 + 12 33 | 34 | ``` 35 | 36 | *** =solution 37 | ```{r} 38 | # 計算 3 + 4 39 | 3 + 4 40 | 41 | # 計算 6 + 12 42 | 6 + 12 43 | ``` 44 | 45 | *** =sct 46 | ```{r} 47 | test_output_contains("7", incorrect_msg = "不需要移除計算 3 加 4 的程式,加另外一行程式計算 6 加 12 即可。") 48 | test_output_contains("18", incorrect_msg = "檢查是否有加入程式計算 6 加 12,注意不要在程式前加上 #,不然該行程式不會被執行!") 49 | success_msg("太棒了!看到 R Console 如何呈現你執行的程式了嗎?既然熟悉了介面,接下來讓我們深入研究 R 吧!") 50 | ``` 51 | 52 | --- type:NormalExercise xp:100 skills:1 key:f50c65ca40332b98e2a74aa17a600d110bc87a81 53 | ## R 與數學運算 54 | 55 | R 可以做為一個簡單的計算機,我們可以利用下列運算符號做簡易的數學運算: 56 | 57 | - 加法: `+` 58 | - 減法: `-` 59 | - 乘法: `*` 60 | - 除法: `/` 61 | - 次方: `^` 62 | - 餘數: `%%` 63 | 64 | 讓我們多解釋一下最後兩個運算符號: 65 | 66 | - `^` 回傳左邊的數字連續自乘右方的數字次數,例如: 3 ^ 2 運算結果為 9。 67 | - `%%` 回傳左邊的數字除以右邊的數字之餘數,例如:5 %% 3 運算結果為 2。 68 | 69 | 根據上述的解釋,照著下方說明完成練習。 70 | 71 | *** =instructions 72 | - 在編輯區中輸入 `2 ^ 5` 來計算 2 的 5 次方。 73 | - 在編輯區中輸入 `28 %% 6` 來求得 28 除以 6 的餘數。 74 | - 按下 Submit Answer 並在 R Console 中查看運算結果。 75 | - 注意:`#` 用來將程式加上註解。 76 | 77 | *** =hint 78 | 另外一個餘數運算範例是: `9 %% 2` ,運算結果會得到 `1`。 79 | 80 | *** =pre_exercise_code 81 | ```{r} 82 | # no pec 83 | ``` 84 | 85 | *** =sample_code 86 | ```{r} 87 | # 加法 88 | 5 + 5 89 | 90 | # 減法 91 | 5 - 5 92 | 93 | # 乘法 94 | 3 * 5 95 | 96 | # 除法 97 | (5 + 5) / 2 98 | 99 | # 次方 100 | 101 | 102 | # 餘數 103 | 104 | ``` 105 | 106 | *** =solution 107 | ```{r} 108 | # 加法 109 | 5 + 5 110 | 111 | # 減法 112 | 5 - 5 113 | 114 | # 乘法 115 | 3 * 5 116 | 117 | # 除法 118 | (5 + 5) / 2 119 | 120 | # 次方 121 | 2 ^ 5 122 | 123 | # 餘數 124 | 28 %% 6 125 | ``` 126 | 127 | *** =sct 128 | ```{r} 129 | msg = "不需要移除其他的數學運算範例!" 130 | test_output_contains("5 + 5", incorrect_msg = msg) 131 | test_output_contains("5 - 5", incorrect_msg = msg) 132 | test_output_contains("3 * 5", incorrect_msg = msg) 133 | test_output_contains("(5 + 5)/2", incorrect_msg = msg) 134 | test_output_contains("2^5", incorrect_msg = "次方的練習不正確,再詳細閱讀一次說明。") 135 | test_output_contains("28 %% 6", incorrect_msg = "餘數的練習不正確,再詳細閱讀一次說明。") 136 | success_msg("太好了!前進下一個練習吧。") 137 | ``` 138 | 139 | 140 | --- type:NormalExercise xp:100 skills:1 key:2ac26323b43f5ce728fb1e29e18d3afc84160fdc 141 | ## 宣告變數 142 | 143 | R 的基本概念是**變數**。 144 | 145 | 使用 R 時,你可以用變數儲存一個值(例如:4),或物件(像是:函數),之後就可以用變數名稱來使用這個值或物件。 146 | 147 | 你可以用下面這行程式,宣告變數 `my_var` 並且將 4 這個數值指派給它: 148 | 149 | ``` 150 | my_var <- 4 151 | ``` 152 | 153 | 接下來你只需要輸入 `my_var`,R Console 就會將 4 印出來: 154 | 155 | ``` 156 | > my_var 157 | [1] 4 158 | ``` 159 | 160 | *** =instructions 161 | 輪到你囉!在編輯區宣告一個變數 `x` 並且將 42 這個數值指派給它,完成之後按下 Submit Answer。接下來你只需要直接輸入 `x`,R Console 就會印出 42。 162 | 163 | *** =hint 164 | 觀察一下如何將 4 指派給 `my_var` 並且在編輯區中做一樣的事情,但是現在將 42 指派給變數 `x`。 165 | 166 | *** =pre_exercise_code 167 | ```{r} 168 | # no pec 169 | ``` 170 | 171 | *** =sample_code 172 | ```{r} 173 | # 宣告變數 x 並將 42 指派給 x 174 | x <- 175 | 176 | # 將變數 x 的值印出 177 | x 178 | ``` 179 | 180 | *** =solution 181 | ```{r} 182 | # 宣告變數 x 並將 42 指派給 x 183 | x <- 42 184 | 185 | # 將變數 x 的值印出 186 | x 187 | ``` 188 | 189 | *** =sct 190 | ```{r} 191 | test_object("x", undefined_msg = "確認是否有宣告變數 `x`。", 192 | incorrect_msg = "確認是否有指派正確的數值給 `x`。") 193 | success_msg("作得好!有注意到嗎?在宣告變數的時候,R 並沒有將變數的值印出?") 194 | ``` 195 | 196 | 197 | --- type:NormalExercise xp:100 skills:1 key:2cb4878a22c17d2f5589992697d96223082a42b9 198 | ## 宣告變數(2) 199 | 200 | 假設一個水果籃中有 5 顆蘋果,身為一個資料分析師,你希望宣告一個變數稱作 `my_apples` 並將蘋果的個數指派給它。 201 | 202 | *** =instructions 203 | - 在編輯區中輸入: `my_apples <- 5` ,這會將5指派給 `my_apples`。 204 | - 在第二個註解下輸入: `my_apples`,這會在R Console中將 `my_apples` 的值印出。 205 | - 完成之後按下 Submit Answer 並且觀察 R Console:你可以發現 5 被印出了,所以 R 已經將 `my_apples` 跟 5 這個數值連結在一起了。 206 | 207 | *** =hint 208 | 記得,要指派數值或物件給變數時,可以使用 `<-` 來指派。也可以使用 `=`,但是 R 社群大多偏好使用 `<-`。 209 | 210 | *** =pre_exercise_code 211 | ```{r} 212 | # no pec 213 | ``` 214 | 215 | *** =sample_code 216 | ```{r} 217 | # 指派 5 這個數值給 my_apples 218 | 219 | 220 | # 將 my_apples 的值印出 221 | 222 | ``` 223 | 224 | *** =solution 225 | ```{r} 226 | # 指派 5 這個數值給 my_apples 227 | my_apples <- 5 228 | 229 | # 將 my_apples 的值印出 230 | my_apples 231 | ``` 232 | 233 | *** =sct 234 | ```{r} 235 | test_object("my_apples", 236 | undefined_msg = "請確認是否有宣告變數 `my_apples`。", 237 | incorrect_msg = "請確認是否有指派正確的數值給 `my_apples`。") 238 | test_output_contains("my_apples", 239 | incorrect_msg = "你是否有告訴R要將 `my_apples` 的值印出?") 240 | success_msg("太好了!前進到下一個練習!") 241 | ``` 242 | 243 | 244 | --- type:NormalExercise xp:100 skills:1 key:a666eb3fb98a7b8cc5930d9c8d2a6997a47561e2 245 | ## 宣告變數(3) 246 | 247 | 美味的水果籃可不能沒有柳橙!當你決定加入 6 個柳橙,身為資料分析師,你的直覺反應會是宣告變數 my_oranges 並指派 6 給它。既然已經完成變數宣告,接下來,如果要計算水果籃內的水果總數,就可以用清楚的方式來寫程式計算: 248 | 249 | ``` 250 | my_apples + my_oranges 251 | ``` 252 | 253 | *** =instructions 254 | - 宣告 `my_oranges` 並指派 6 給它。 255 | - 將 `my_apples` 與 `my_oranges` 相加並將結果印出。 256 | - 要計算水果籃裡頭的水果總數,將 `my_apples` 與 `my_oranges` 相加並指派給一個新變數 `my_fruit`。 257 | 258 | *** =hint 259 | `my_fruit` 單純就是 `my_apples` 加 `my_oranges`。只要使用 `+` 就可以進行相加,之後再使用 `<-` 將結果指派給 `my_fruit`。 260 | 261 | *** =pre_exercise_code 262 | ```{r} 263 | # no pec 264 | ``` 265 | 266 | *** =sample_code 267 | ```{r} 268 | # 宣告 my_apples 與 my_oranges 並分別指派蘋果個數為 5、柳橙個數為 6 269 | my_apples <- 5 270 | 271 | 272 | # 相加兩個變數然後印出結果 273 | 274 | 275 | # 宣告變數 my_fruit 276 | 277 | ``` 278 | 279 | *** =solution 280 | ```{r} 281 | # 宣告 my_apples 與 my_oranges 並分別指派蘋果個數為 5、柳橙個數為 6 282 | my_apples <- 5 283 | my_oranges <- 6 284 | 285 | # 相加兩個變數然後印出結果 286 | my_apples + my_oranges 287 | 288 | # 宣告變數 my_fruit 289 | my_fruit <- my_apples + my_oranges 290 | ``` 291 | 292 | *** =sct 293 | ```{r} 294 | test_object("my_apples", 295 | undefined_msg = "請確認是否有宣告變數 `my_apples`。", 296 | incorrect_msg = "不要更動變數 `my_apples`!") 297 | test_object("my_oranges", 298 | undefined_msg = "請確認是否有宣告變數 `my_oranges`。", 299 | incorrect_msg = "請確認是否有指派正確的數值給變數 `my_oranges`。") 300 | test_output_contains("my_apples + my_oranges", 301 | incorrect_msg = "請確認是否有新增一行程式 my_apples + my_oranges 印出相加結果。") 302 | test_object("my_fruit", 303 | undefined_msg = "請確認是否有宣告變數`my_fruit`。", 304 | incorrect_msg = "請確認是否有指派正確的數值給變數 `my_fruit`。") 305 | success_msg("作得太好了!使用變數作運算的最大好處就是可以重複使用變數。假如將 `my_apples` 由 5 更改為 12,`my_fruit` 的運算結果也會隨之更新。") 306 | ``` 307 | 308 | 309 | --- type:NormalExercise xp:100 skills:1 key:ff7bb3bd1c38b5db3ce9dde0e45f275163b6a9b6 310 | ## 蘋果與柳橙 311 | 312 | 常識告訴你把蘋果與柳橙相加是很愚蠢的:-) 在前一個練習中, `my_apples` 與 `my_oranges` 這兩個變數各自擁有一個數值,在 R 中可以使用 `+` 作數值的相加。但是,若我們是指派文字給 `my_oranges` (如編輯區所示),則表示我們試著將數值與文字作加總運算,且將其結果指派給 `my_fruit`,這是絕對行不通的。 313 | 314 | *** =instructions 315 | - 按下 Submit Answer 並觀察錯誤訊息,了解為什麼會產生這個錯誤訊息。 316 | - 修正這段程式讓 R 知道你有 6 個柳橙,所以水果籃中共有 11 個水果。 317 | 318 | *** =hint 319 | 你必須將數值 `6` 指派給變數 `my_oranges` 而非原本的文字 `"six"`。 注意雙引號是用來告訴 R `"six"` 是一個文字。 320 | 321 | *** =pre_exercise_code 322 | ```{r} 323 | # no pec 324 | ``` 325 | 326 | *** =sample_code 327 | ```{r} 328 | # 宣告變數 my_apples 並將 5 指派給它 329 | my_apples <- 5 330 | 331 | # 將 my_apples 的值印出 332 | my_apples 333 | 334 | # 宣告變數 my_oranges 並將 "six" 指派給它,然後再把 my_oranges 印出 335 | my_oranges <- "six" 336 | my_oranges 337 | 338 | # 宣告變數 my_fruit 並將 my_apples 與 my_oranges 相加後指派給它 339 | my_fruit <- my_apples + my_oranges 340 | my_fruit 341 | ``` 342 | 343 | *** =solution 344 | ```{r} 345 | # 宣告變數 my_apples 並將 5 指派給它 346 | my_apples <- 5 347 | 348 | # 將 my_apples 的值印出 349 | my_apples 350 | 351 | # 宣告變數 my_oranges 並將 "six" 指派給它,然後再把 my_oranges 印出 352 | my_oranges <- 6 353 | my_oranges 354 | 355 | # 宣告變數 my_fruit 並將 my_apples 與 my_oranges 相加後指派給它 356 | my_fruit <- my_apples + my_oranges 357 | my_fruit 358 | ``` 359 | 360 | *** =sct 361 | ```{r} 362 | #test_error() 363 | test_object("my_apples", 364 | undefined_msg = "請確認是否有宣告變數 `my_apples`。", 365 | incorrect_msg = "不要更動變數 `my_apples`!") 366 | test_object("my_oranges", 367 | incorrect_msg = "確認是否有指派正確的數值給 `my_oranges`。 字串與數值是不一樣的喔!") 368 | test_output_contains("my_apples + my_oranges", 369 | incorrect_msg = "輸出並沒有包含 `my_apples` 加 `my_oranges`的結果。") 370 | test_object("my_fruit", 371 | incorrect_msg = "確認是否有指派正確的數值給 `my_fruit`。") 372 | success_msg("太棒了,請繼續保持!前進下一個練習。") 373 | ``` 374 | 375 | 376 | --- type:NormalExercise xp:100 skills:1 key:40c0d484b0ed0826822600b7c1d896d155e3e411 377 | ## R 的基本資料類別 378 | 379 | R 可以運算多種的資料類別,其中較為基本的有: 380 | 381 | - 有小數點的如 `4.5` 稱為**數值**。 382 | - 自然數如 `4` 稱為**整數**,整數同時也屬於數值。 383 | - 布林值(`TRUE` or `FALSE`)稱為**邏輯值**。 384 | - 字元(或者字串)稱為**文字**。 385 | 386 | 用雙引號包起來的文字、數值、符號...,都可以讓 R 知道這是一個字串,例如:"嗨"、"apple"、"123"、"$#@"。 387 | 388 | *** =instructions 389 | 更改變數的數值: 390 | 391 | - 將 `my_numeric` 指派為 `42`。 392 | - 將 `my_character` 指派為 `"universe"`。 用雙引號包起來的就可以讓 R 知道 `"universe"` 是一個文字。 393 | - 將 `my_logical` 指派為 `FALSE`。 394 | 395 | 注意英文字母的大小寫在 R 是有差別的! 396 | 397 | *** =hint 398 | 在編輯區將數值、文字與邏輯值重新指派: 399 | `my_numeric <- 42` 可將 42 指派給變數 `my_numeric`。 400 | `my_character <- "universe"` 可將 "universe" 指派給變數 `my_character`。 401 | `my_logical <- FALSE` 可將 FALSE 指派給 `my_logical`。 402 | 403 | *** =pre_exercise_code 404 | ```{r} 405 | # no pec 406 | ``` 407 | 408 | *** =sample_code 409 | ```{r} 410 | # 指派 42 給 my_numeric 411 | my_numeric <- 42.5 412 | 413 | # 指派 "universe" 給 my_character 414 | my_character <- "some text" 415 | 416 | # 指派 FALSE 給 my_logical 417 | my_logical <- TRUE 418 | ``` 419 | 420 | *** =solution 421 | ```{r} 422 | # 指派 42 給 my_numeric 423 | my_numeric <- 42 424 | 425 | # 指派 "universe" 給 my_character 426 | my_character <- "universe" 427 | 428 | # 指派 FALSE 給 my_logical 429 | my_logical <- FALSE 430 | ``` 431 | 432 | *** =sct 433 | ```{r} 434 | test_object("my_numeric", incorrect_msg = "確認是否將42指派給變數 `my_numeric`?") 435 | test_object("my_character", incorrect_msg = "確認是否將 `\"universe\"` 指派給 `my_character`?別忘了用雙引號把字串包起來!") 436 | test_object("my_logical", incorrect_msg = "確認是否將 `FALSE` 指派給 `my_logical`?注意 `FALSE` 每個字母都要使用大寫!") 437 | success_msg("作得太好了!繼續前進下一個練習吧!") 438 | ``` 439 | 440 | 441 | --- type:NormalExercise xp:100 skills:1 key:3c8cc5a936ede8b77b123fda57e937afe5cf1f70 442 | ## 如何判斷資料類別? 443 | 444 | 還記得先前在執行 `5 + "six"` 時,因為資料類別不同而得到錯誤訊息嗎?為了避免這類尷尬的情況發生,我們可善用右方編輯區中的 `class()` 函數,來事先檢視資料的類別。 445 | 446 | *** =instructions 447 | 完成編輯區的程式並將 `my_character` 與 `my_logical` 的資料類別印出。 448 | 449 | *** =hint 450 | 參考範例如何將`my_numeric`的資料類別印出,用同樣的方式把 `my_character` 與 `my_logical` 的資料類別也印出來。 451 | 452 | *** =pre_exercise_code 453 | ```{r} 454 | # no pec 455 | ``` 456 | 457 | *** =sample_code 458 | ```{r} 459 | # 宣告不同種類的變數 460 | my_numeric <- 42 461 | my_character <- "universe" 462 | my_logical <- FALSE 463 | 464 | # 檢查 my_numeric 的類別 465 | class(my_numeric) 466 | 467 | # 檢查 my_character 的類別 468 | 469 | 470 | # 檢查 my_logical 的類別 471 | 472 | ``` 473 | 474 | *** =solution 475 | ```{r} 476 | # 宣告不同種類的變數 477 | my_numeric <- 42 478 | my_character <- "universe" 479 | my_logical <- FALSE 480 | 481 | # 檢查 my_numeric 的類別 482 | class(my_numeric) 483 | 484 | # 檢查 my_character 的類別 485 | class(my_character) 486 | 487 | # 檢查 my_logical 的類別 488 | class(my_logical) 489 | ``` 490 | 491 | *** =sct 492 | ```{r} 493 | msg <- "不需要更改變數的宣告。" 494 | lapply(c("my_numeric", "my_character", "my_logical"), test_object, undefined_msg = msg, incorrect_msg = msg) 495 | patt <- "確認你是否有使用 `class(%1$s)` 來印出 `%1$s` 的資料類別?" 496 | test_output_contains("class(my_numeric)", 497 | incorrect_msg = "不需要移除印出 `my_numeric` 資料類別的程式") 498 | test_output_contains("class(my_character)", 499 | incorrect_msg = sprintf(patt, "my_character")) 500 | test_output_contains("class(my_logical)", 501 | incorrect_msg = sprintf(patt, "my_logical")) 502 | success_msg("恭喜你完成了本章節的最後一個練習,讓我們前進下個章節來研究向量吧!") 503 | ``` 504 | 505 | 506 | 507 | -------------------------------------------------------------------------------- /chapter4.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : 第四章 3 | title : 因素向量 4 | description : 資料常會有特定幾個類別,例如性別是男或女。在 R 語言,類別型的資料以因素向量的方式儲存,因素向量對資料分析是很重要的,讓我們好好學習如何建立、篩選與比較因素向量! 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:226aa2797e77894b2083c4471f92b23aae435823 7 | ## 因素向量是什麼?你為什麼要使用它? 8 | 9 | 在本章節中你會進入**因素向量**的美麗世界。 10 | 11 | 因素向量是用來儲存類別型變數的統計資料,類別型變數與連續型變數最主要的差異在於類別型變數有**類別個數的上限**,而連續型變數則會有無窮多的個數。 12 | 13 | 在未來你要處理的統計模型中,對連續變數與類別變數之間的差異非常地重要,所以必須讓R知道在處理哪一種類型的變數。 14 | 15 | 一個很好的因素向量範例是性別,生理上的區分可分成男性與女性,因此每一個觀測值都可以被分類成生理男性或生理女性。 16 | 17 | *** =instructions 18 | 宣告變數 `theory` 並指派 `"factors for categorical variables"` 給它。 19 | 20 | *** =hint 21 | 使用指派運算子 (`<-`) 並確認字母大小寫是否正確。 22 | 23 | *** =pre_exercise_code 24 | ```{r} 25 | # no pec 26 | ``` 27 | 28 | *** =sample_code 29 | ```{r} 30 | # 宣告變數 theory 31 | ``` 32 | 33 | *** =solution 34 | ```{r} 35 | # 宣告變數 theory 36 | theory <- "factors for categorical variables" 37 | ``` 38 | 39 | *** =sct 40 | ```{r} 41 | test_object("theory", incorrect_msg = "確認是否將文字 `\"factors for categorical variables\"` 指派給 `theory`,注意字母的大小寫對R是有差別的。"); 42 | success_msg("作得好,前進下一個練習!") 43 | ``` 44 | 45 | 46 | --- type:NormalExercise xp:100 skills:1 key:86d03f14e0b95e7cdc8cc5163493a156313bf8c6 47 | ## 因素向量是什麼?你為什麼要使用它?(2) 48 | 49 | R 使用[`factor()`](http://www.rdocumentation.org/packages/base/functions/factor)函數來宣告因素向量,首先,建立一個具有類別型觀測值的向量,例如 5 個人的性別 `gender_vector`: 50 | 51 | ``` 52 | gender_vector <- c("Male","Female","Female","Male","Male") 53 | ``` 54 | 55 | `gender_vector` 明顯地只有 2 種類別,或用 R 術語來解釋:**因素向量的類別為** "Male" 與 "Female"。 56 | 57 | [`factor()`](http://www.rdocumentation.org/packages/base/functions/factor)函數會將向量轉換成因素向量: 58 | 59 | ``` 60 | factor_gender_vector <- factor(gender_vector) 61 | ``` 62 | 63 | *** =instructions 64 | - 利用 `factor()` 將 `gender_vector` 轉換成因素向量並將結果指派給 `factor_gender_vector`。 65 | - 印出 `factor_gender_vector` 並注意 R 會把因素向量的層級顯示在實際值下。 66 | 67 | *** =hint 68 | 對 `gender_vector` 使用[`factor()`](http://www.rdocumentation.org/packages/base/functions/factor)函數,再閱讀一下說明,答案已經呼之欲出了... 69 | 70 | *** =pre_exercise_code 71 | ```{r} 72 | # no pec 73 | ``` 74 | 75 | *** =sample_code 76 | ```{r} 77 | # 性別向量 78 | gender_vector <- c("Male", "Female", "Female", "Male", "Male") 79 | 80 | # 轉換 gender_vector 成為因素向量 81 | factor_gender_vector <- 82 | 83 | # 印出 factor_gender_vector 84 | 85 | ``` 86 | 87 | *** =solution 88 | ```{r} 89 | # 性別向量 90 | gender_vector <- c("Male", "Female", "Female", "Male", "Male") 91 | 92 | # 轉換 gender_vector 成為因素向量 93 | factor_gender_vector <- factor(gender_vector) 94 | 95 | # 印出 factor_gender_vector 96 | factor_gender_vector 97 | ``` 98 | 99 | *** =sct 100 | ```{r} 101 | test_object("factor_gender_vector", 102 | incorrect_msg = "確認是否將 `gender_vector` 轉化成 `factor_gender_vector`?") 103 | test_output_contains("factor_gender_vector", incorrect_msg = "別忘了把 `factor_gender_vector` 印出!") 104 | success_msg("太棒了,只要在 R Console 輸入 `?factor` 就可以了解更多關於 `factor()`函數的內容,前進下一個練習!"); 105 | ``` 106 | 107 | 108 | --- type:NormalExercise xp:100 skills:1 key:43072d1299a99d76130f1e45dedf09baac8c8481 109 | ## 因素向量是什麼?你為什麼要使用它?(3) 110 | 111 | 類別型變數可分為**名目類別型變數**與**順序類別型變數**兩種。 112 | 113 | 名目類別型變數即是無法在類別之間比較好壞,例如一個變數 `animals_vector` 中有 `"Elephant"` 、 `"Giraffe"` 、 `"Donkey"` 與 `"Horse"`,要知道你可無法比較動物之間的好壞優劣! 114 | 115 | 相對來說,順序類別型變數具有天生的比較特性,例如一個變數 `temperature_vector` 中有 `"Low"` 、 `"Medium"` 與 `"High"`,很明顯 `"Medium"` 比 `"Low"` 高而 `"High"` 又比 `"Medium"` 來得要高. 116 | 117 | *** =instructions 118 | 按下 Submit Answer 來檢查 R 如何建立並印出名目與順序變數,不需要擔心不了解這些程式,我們之後會學。 119 | 120 | *** =hint 121 | 按下 Submit Answer 並觀察 R Console,注意 R 如何為順序類別型變數編排因素類別。 122 | 123 | *** =pre_exercise_code 124 | ```{r} 125 | # no pec 126 | ``` 127 | 128 | *** =sample_code 129 | ```{r} 130 | # 動物 131 | animals_vector <- c("Elephant", "Giraffe", "Donkey", "Horse") 132 | factor_animals_vector <- factor(animals_vector) 133 | factor_animals_vector 134 | 135 | # 溫度 136 | temperature_vector <- c("High", "Low", "High","Low", "Medium") 137 | factor_temperature_vector <- factor(temperature_vector, order = TRUE, levels = c("Low", "Medium", "High")) 138 | factor_temperature_vector 139 | ``` 140 | 141 | *** =solution 142 | ```{r} 143 | # 動物 144 | animals_vector <- c("Elephant", "Giraffe", "Donkey", "Horse") 145 | factor_animals_vector <- factor(animals_vector) 146 | factor_animals_vector 147 | 148 | # 溫度 149 | temperature_vector <- c("High", "Low", "High","Low", "Medium") 150 | factor_temperature_vector <- factor(temperature_vector, order = TRUE, levels = c("Low", "Medium", "High")) 151 | factor_temperature_vector 152 | ``` 153 | 154 | *** =sct 155 | ```{r} 156 | msg <- "不需要更改示範程式碼,按Submit Answer按鈕之後看結果。" 157 | test_object("animals_vector", undefined_msg = msg, incorrect_msg = msg) 158 | test_object("temperature_vector", undefined_msg = msg, incorrect_msg = msg) 159 | test_object("factor_animals_vector", undefined_msg = msg, incorrect_msg = msg) 160 | test_output_contains("factor_animals_vector", incorrect_msg = msg) 161 | test_object("factor_temperature_vector", undefined_msg = msg, incorrect_msg = msg) 162 | test_output_contains("factor_temperature_vector", incorrect_msg = msg) 163 | success_msg("有看出這個練習告訴你們什麼事了嗎?太棒了,前進下一個練習並看出因素向量的細節。") 164 | ``` 165 | 166 | 167 | --- type:NormalExercise xp:100 skills:1 key:d209a65b768975156e39f18fe6e982b30a8b99d9 168 | ## 因素向量級別 169 | 170 | 有時候你會想改變因素向量級別的名稱,可以使用[`levels()`](http://www.rdocumentation.org/packages/base/functions/levels)函數辦到: 171 | 172 | ``` 173 | levels(factor_vector) <- c("name1", "name2",...) 174 | ``` 175 | 176 | 一般問卷都會記錄受訪者的性別,在前一個練習中我們知道性別是一種因素向量,在問卷資料中 `"M"` 與 `"F"` 分別代表著男性與女性。 177 | 178 | ``` 179 | survey_vector <- c("M", "F", "F", "M", "M") 180 | ``` 181 | 182 | 為了對資料能夠一目瞭然,我們想將男性與女性分別用 `"Male"` 與 `"Female"` 來表示,取代原本的 `"M"` 與 `"F"`。 183 | 184 | **注意:**在改變名稱的時候輸入順序非常重要,在 R Console 輸入 `levels(factor_survey_vector)` 會得到輸出為 `[1] "F" "M"` ,這代表 R 預設是以字母順序排列,因此當你要重新編名稱的時候,你應該要輸入 `levels(factor_survey_vector) <- c("Female", "Male")` 這樣才能正確地把 "F" 對應到 "Female"、把 "M" 對應到 "Male"。 185 | 186 | *** =instructions 187 | - 檢視已經寫好的程式。 188 | - 將 `factor_survey_vector` 的級別從 `"F"` 與 `"M"`改為 `c("Female", "Male")`,注意 "Female" 與 "Male" 擺放的順序。 189 | 190 | *** =hint 191 | 留意你輸入級別名稱的順序,提示:先在 R Console 輸入 `levels(factor_survey_vector)` 就會知道重新命名的正確順序。 192 | 193 | *** =pre_exercise_code 194 | ```{r} 195 | # no pec 196 | survey_vector <- c("M", "F", "F", "M", "M") 197 | factor_survey_vector <- factor(survey_vector) 198 | ``` 199 | 200 | *** =sample_code 201 | ```{r} 202 | # 建立 factor_survey_vector 203 | survey_vector <- c("M", "F", "F", "M", "M") 204 | factor_survey_vector <- factor(survey_vector) 205 | 206 | # 指定 factor_survey_vector 的名稱 207 | levels(factor_survey_vector) <- 208 | 209 | factor_survey_vector 210 | ``` 211 | 212 | *** =solution 213 | ```{r} 214 | # 建立 factor_survey_vector 215 | survey_vector <- c("M", "F", "F", "M", "M") 216 | factor_survey_vector <- factor(survey_vector) 217 | 218 | # 指定 factor_survey_vector 的名稱 219 | levels(factor_survey_vector) <- c("Female", "Male") 220 | 221 | factor_survey_vector 222 | ``` 223 | 224 | *** =sct 225 | ```{r} 226 | msg = "不需要更改 `survey_vector` 的宣告。" 227 | test_object("survey_vector", undefined_msg = msg, incorrect_msg = msg) 228 | msg = "不需要更改或移除建立因素向量的程式。" 229 | test_function("factor", "x", not_called_msg = msg, incorrect_msg = msg) 230 | test_object("factor_survey_vector", eq_condition = "equal", 231 | incorrect_msg = paste("確認是否指派正確的名稱給了 `factor_survey_vector`?利用 `levels(factor_survey_vector) <- c(\"Female\", \"Male\")` 並注意大小寫對R是不一樣的!")) 232 | success_msg("完美,前進下一個練習!") 233 | ``` 234 | 235 | 236 | --- type:NormalExercise xp:100 skills:1 key:1a2235a13a67daf9c186b963a57c9a206a7f43ba 237 | ## 因素向量的摘要 238 | 239 | 在這個練習之後,[`summary()`](http://www.rdocumentation.org/packages/base/functions/summary)函數會變成你最喜歡的函數之一!`summary()` 能讓我們快速得到一組資料的摘要: 240 | 241 | ``` 242 | summary(my_var) 243 | ``` 244 | 245 | 讓我們繼續看問卷,你想知道分別有多少男性與女性的受試者填寫了問卷,[`summary()`](http://www.rdocumentation.org/packages/base/functions/summary)函數會給你答案。 246 | 247 | *** =instructions 248 | 對 `survey_vector` 與 `factor_survey_vector` 使用 [`summary()`](http://www.rdocumentation.org/packages/base/functions/summary) 函數,並且比較這兩個結果是否相同? 249 | 250 | *** =hint 251 | 對 `survey_vector` 與 `factor_survey_vector` 使用 [`summary()`](http://www.rdocumentation.org/packages/base/functions/summary) 函數,就這麼單純! 252 | 253 | *** =pre_exercise_code 254 | ```{r} 255 | # no pec 256 | ``` 257 | 258 | *** =sample_code 259 | ```{r} 260 | # 建立有清楚級別的 factor_survey_vector 261 | survey_vector <- c("M", "F", "F", "M", "M") 262 | factor_survey_vector <- factor(survey_vector) 263 | levels(factor_survey_vector) <- c("Female", "Male") 264 | factor_survey_vector 265 | 266 | # 產出 survey_vector 的摘要 267 | 268 | 269 | # 產出 factor_survey_vector 的摘要 270 | 271 | ``` 272 | 273 | *** =solution 274 | ```{r} 275 | # 建立有清楚級別的 factor_survey_vector 276 | survey_vector <- c("M", "F", "F", "M", "M") 277 | factor_survey_vector <- factor(survey_vector) 278 | levels(factor_survey_vector) <- c("Female", "Male") 279 | factor_survey_vector 280 | 281 | # 產出 survey_vector 的摘要 282 | summary(survey_vector) 283 | 284 | # 產出 factor_survey_vector 的摘要 285 | summary(factor_survey_vector) 286 | ``` 287 | 288 | *** =sct 289 | ```{r} 290 | msg = "不需要更改宣告 `survey_vector` 與 `factor_survey_vector` 的程式。" 291 | test_object("survey_vector", undefined_msg = msg, incorrect_msg = msg, eq_condition = "equal") 292 | test_object("factor_survey_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 293 | msg <- "確認是否正確使用 `summary()` 來產出 `%s` 的摘要?" 294 | test_function("summary", index = 1, args = "object", not_called_msg = sprintf(msg, "survey_vector"), incorrect_msg = sprintf(msg, "survey_vector")) 295 | test_function("summary", index = 2, args = "object", not_called_msg = sprintf(msg, "factor_survey_vector"), incorrect_msg = sprintf(msg, "factor_survey_vector")) 296 | success_msg("太棒了,觀察一下 R Console 的輸出,因為你將 `factor_survey_vector` 指派為因素向量,所以 R 會顯示出每個類別的個數!") 297 | ``` 298 | 299 | 300 | --- type:NormalExercise xp:100 skills:1 key:9247612eea708b363b23b58a9fdff76ba50818e9 301 | ## 兩性戰爭 302 | 303 | `factor_survey_vector` 是有兩個級別的因素向量:男性與女性。但 R 是否有比較這兩個級別的好壞優劣呢? 304 | 305 | *** =instructions 306 | 讀編輯區的程式然後按下 Submit Answer 看看男性是否比女性來得差勁。 307 | 308 | *** =hint 309 | 按 Submit Answer 並看看 R Console 的輸出。 310 | 311 | *** =pre_exercise_code 312 | ```{r} 313 | # no pec 314 | ``` 315 | 316 | *** =sample_code 317 | ```{r} 318 | # 建立有清楚級別的 factor_survey_vector 319 | survey_vector <- c("M", "F", "F", "M", "M") 320 | factor_survey_vector <- factor(survey_vector) 321 | levels(factor_survey_vector) <- c("Female", "Male") 322 | 323 | # 男性 324 | male <- factor_survey_vector[1] 325 | 326 | # 女性 327 | female <- factor_survey_vector[2] 328 | 329 | # 兩性戰爭:男性'大於'女性? 330 | male > female 331 | ``` 332 | 333 | *** =solution 334 | ```{r} 335 | # 建立有清楚級別的 factor_survey_vector 336 | survey_vector <- c("M", "F", "F", "M", "M") 337 | factor_survey_vector <- factor(survey_vector) 338 | levels(factor_survey_vector) <- c("Female", "Male") 339 | 340 | # 男性 341 | male <- factor_survey_vector[1] 342 | 343 | # 女性 344 | female <- factor_survey_vector[2] 345 | 346 | # 兩性戰爭:男性'大於'女性? 347 | male > female 348 | ``` 349 | 350 | *** =sct 351 | ```{r} 352 | msg = "不需要更改程式,按送出答案並檢視結果。" 353 | test_object("survey_vector", undefined_msg = msg, incorrect_msg = msg) 354 | test_object("factor_survey_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 355 | test_object("male", undefined_msg = msg, incorrect_msg = msg) 356 | test_object("female", undefined_msg = msg, incorrect_msg = msg) 357 | test_output_contains("male > female", incorrect_msg = msg) 358 | success_msg("呼...好險,看起來 R 是沒有性別歧視的!") 359 | ``` 360 | 361 | 362 | --- type:NormalExercise xp:100 skills:1 key:a25f8ec566840068e4065b4af557ffe8eefa0b53 363 | ## 順序型因素向量 364 | 365 | 既然 `"Male"` 與 `"Female"` 是沒有順序的(或者說是名目),所以 R 回傳了警告訊息,告訴你 `>` 運算子是沒有意義的,R 把它們視為相等。 366 | 367 | 但你有時還是得處理那些具有天生順序性的類別變數,這時我們得要特別把這個訊息告訴 R 才行... 368 | 369 | 假如你管理一個有 5 個資料分析師的研究團隊,你衡量他們的執行效率後將他們歸類為 "slow"、"fast" 與 "insane",然後把結果指派給一個向量 `speed_vector`。 370 | 371 | *** =instructions 372 | 第一步我們要宣告 `speed_vector` : 373 | 374 | - 分析師 1 是 fast, 375 | - 分析師 2 是 slow, 376 | - 分析師 3 是 slow, 377 | - 分析師 4 是 fast, 378 | - 分析師 5 是 insane。 379 | 380 | 還不需要指定為因素向量。 381 | 382 | *** =hint 383 | 宣告 `speed_vector` 並指派一個字串向量 `"fast"` 、 `"slow"` 給它。 384 | 385 | *** =pre_exercise_code 386 | ```{r} 387 | # no pec 388 | ``` 389 | 390 | *** =sample_code 391 | ```{r} 392 | # 宣告 speed_vector 393 | speed_vector <- 394 | ``` 395 | 396 | *** =solution 397 | ```{r} 398 | # 宣告 speed_vector 399 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 400 | ``` 401 | 402 | *** =sct 403 | ```{r} 404 | test_object("speed_vector", 405 | incorrect_msg = "確認你是否有將正確的字串指派給 `speed_vector`,不要使用大寫英文字,大小寫對R是不同的!") 406 | success_msg("作得好,前進下一個練習!") 407 | ``` 408 | 409 | 410 | --- type:NormalExercise xp:100 skills:1 key:52c40d180e9661fd82e138f210eef258a81e51e1 411 | ## 順序型因素向量(2) 412 | 413 | `speed_vector` 接下來會被轉換為順序型因素向量,因為速度是有快慢之分的。直接使用[`factor()`](http://www.rdocumentation.org/packages/base/functions/factor)函數預設會將 `speed_vector` 轉換成非順序型的因素向量,為了建立一個順序型因素向量,你必須加入 2 個額外參數: `ordered` 與 `levels`。 414 | 415 | ``` 416 | factor(some_vector, 417 | ordered = TRUE, 418 | levels = c("lev1", "lev2" ...)) 419 | ``` 420 | 421 | 在[`factor()`](http://www.rdocumentation.org/packages/base/functions/factor)函數中設定參數 `ordered` 為 `TRUE` 指定這個因素向量是順序型的,而參數 `levels` 則讓你給定正確的順序。 422 | 423 | *** =instructions 424 | 將 `speed_vector` 轉換為 `factor_speed_vector` 並將 `ordered` 指定為 `TRUE` 並設定 `levels` 為 `c("slow", "fast", "insane")`。 425 | 426 | *** =hint 427 | 呼叫[`factor()`](http://www.rdocumentation.org/packages/base/functions/factor)函數將 `speed_character_vector` 轉換為 `factor_speed_vector`。參數 `ordered` 應該要被設定為 `TRUE` 因為速度是有快慢之分的,另外也要記得設定 `levels = c("slow", "fast", "insane")`. 428 | 429 | *** =pre_exercise_code 430 | ```{r} 431 | # no pec 432 | ``` 433 | 434 | *** =sample_code 435 | ```{r} 436 | # 建立 speed_vector 437 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 438 | 439 | # 轉換 speed_vector 為順序型因素向量 440 | factor_speed_vector <- 441 | 442 | # 印出 factor_speed_vector 與其摘要 443 | 444 | ``` 445 | 446 | *** =solution 447 | ```{r} 448 | # 建立 speed_vector 449 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 450 | 451 | # 轉換 speed_vector 為順序型因素向量 452 | factor_speed_vector <- factor(speed_vector, ordered = TRUE, levels = c("slow", "fast", "insane")) 453 | 454 | # 印出 factor_speed_vector 與其摘要 455 | factor_speed_vector 456 | summary(factor_speed_vector) 457 | ``` 458 | 459 | *** =sct 460 | ```{r} 461 | msg = "不需要更改宣告 `speed_vector` 的程式。" 462 | test_object("speed_vector", undefined_msg = msg, incorrect_msg = msg) 463 | test_function("factor", "x", incorrect_msg = "傳入 `factor()` 的第一個參數應該為 `speed_vector` 。") 464 | test_function("factor", "ordered", incorrect_msg = "確認是否有將參數 `ordered = TRUE` 加入 `factor()` 中。") 465 | test_function("factor", "levels", incorrect_msg = "確認是否有將參數 `levels = c(\"slow\", \"fast\", \"insane\")` 加入 `factor()` 中。") 466 | test_object("factor_speed_vector", eq_condition = "equal", 467 | incorrect_msg = "`factor_speed_vector` 看起來還是有點問題,請確認你有將參數 `speed_vector` 、 `ordered = TRUE` 與 `levels = c(\"slow\", \"fast\", \"insane\")` 放入 `factor()` 中。") 468 | test_function("summary", incorrect_msg = "記得將 `factor_speed_vector` 的摘要印出來!") 469 | success_msg("太棒了,從 R Console 中可以看到 R 用 `<` 符號標示了快慢順序,前進下一個練習!") 470 | ``` 471 | 472 | 473 | --- type:NormalExercise xp:100 skills:1 key:6195cdd81bcd1b66d8dde93500dc2e4df63c58d0 474 | ## 比較順序型因素向量 475 | 476 | 經過一天辛苦的工作,資料分析師 2進來你的辦公室並開始抱怨資料分析師 5 拖垮了整個專案。由於你知道資料分析師 2 是很精明的,你想先檢查一下他說的是否屬實。 477 | 478 | 既然 `factor_speed_vector` 已經排好順序,你可以用 `>` 這個運算子來比較快慢。 479 | 480 | *** =instructions 481 | - 用 `[2]` 把 `factor_speed_vector` 中的第二個資料分析師選出來,指派給 `da2`。 482 | - 用 `[5]` 把 `factor_speed_vector` 中的第五個資料分析師選出來,指派給 `da5`。 483 | - 確認 `da2` 是否比 `da5` 快並印出結果,記得使用 `>` 運算子來檢查哪個元素較大。 484 | 485 | *** =hint 486 | - 你需要輸入 `factor_speed_vector[n]` 來將第 n 個資料分析師選出來。 487 | - 比較 2 個數值可以使用 `>` 例如: `da3 > da4`。 488 | 489 | *** =pre_exercise_code 490 | ```{r} 491 | # no pec 492 | ``` 493 | 494 | *** =sample_code 495 | ```{r} 496 | # 建立 factor_speed_vector 497 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 498 | factor_speed_vector <- factor(speed_vector, ordered = TRUE, levels = c("slow", "fast", "insane")) 499 | 500 | # 選出資料分析師 2 501 | da2 <- 502 | 503 | # 選出資料分析師 5 504 | da5 <- 505 | 506 | # 資料分析師 2 是否比資料分析師 5 快? 507 | 508 | ``` 509 | 510 | *** =solution 511 | ```{r} 512 | # 建立 factor_speed_vector 513 | speed_vector <- c("fast", "slow", "slow", "fast", "insane") 514 | factor_speed_vector <- factor(speed_vector, ordered = TRUE, levels = c("slow", "fast", "insane")) 515 | 516 | # 選出資料分析師 2 517 | da2 <- factor_speed_vector[2] 518 | 519 | # 選出資料分析師 5 520 | da5 <- factor_speed_vector[5] 521 | 522 | # 資料分析師 2 是否比資料分析師 5 快? 523 | da2 > da5 524 | ``` 525 | 526 | *** =sct 527 | ```{r} 528 | msg = "不需要更改任何宣告 `speed_vector` 與 `factor_speed_vector` 的程式。" 529 | test_object("speed_vector", undefined_msg = msg, incorrect_msg = msg) 530 | test_object("factor_speed_vector", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 531 | 532 | msg <- "確認是否有正確選擇出%s資料分析師,你可以使用 `factor_speed_vector[%s]` 來作選擇。" 533 | test_object("da2", eq_condition = "equal", incorrect_msg = sprintf(msg, "第二位", "2")) 534 | test_object("da5", eq_condition = "equal", incorrect_msg = sprintf(msg, "第五位", "5")) 535 | test_output_contains("da2 > da5", incorrect_msg = "確認是否有比較 `da2` 與 `da5`?使用 `>` 並印出結果。") 536 | 537 | success_msg("太美好了,結果告訴了你,其實那個來抱怨資料分析師5的資料分析師2才是那個拖慢專案的人,這是因素向量章節的最後一個練習,現在你有了對向量、矩陣與因素向量的具體想法,你已經準備好要邁入非常重要的資料框!") 538 | ``` 539 | 540 | 541 | 542 | -------------------------------------------------------------------------------- /chapter5.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : 第五章 3 | title : 資料框 4 | description : 實務上我們面對的多數資料都是儲存為資料框的格式,學完本章節之後,我們將可以熟練地建立資料框、選擇資料框中有興趣的部分以及根據某一個變數排序資料框。 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:697536131763a67337978935d895a05e2ed6bfee 7 | ## 資料框是什麼? 8 | 9 | 矩陣中所有的元素都應該是相同類型的,記得你在前一個章節中建立的星際大戰票房矩陣嗎?矩陣裡面的元素全部都是數值。 10 | 11 | 當你做市場調查時,問卷中常常有問題像是: 12 | 13 | - 請問你結婚了嗎?回答為是/否的問題(`邏輯值`) 14 | - 請問你的年紀為?(`數值`) 15 | - 對於本產品的意見?或其他開放式問題(`文字`) 16 | - ... 17 | 18 | 因此問卷的調查結果通常包含了不同類型的資料。 19 | 20 | 資料框中將觀測值儲存為列,將變數儲存為欄,這與其他統計軟體像是 SAS 或 SPSS 的概念是相似的。 21 | 22 | *** =instructions 23 | 按下 Submit Answer。將內建的範例資料框[`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars)印出在 R Console 中。 24 | 25 | *** =hint 26 | 按下 Submit Answer 並觀察結果! 27 | 28 | *** =pre_exercise_code 29 | ```{r} 30 | # no pec 31 | ``` 32 | 33 | *** =sample_code 34 | ```{r} 35 | # 印出內建的 R 資料框 36 | mtcars 37 | ``` 38 | 39 | *** =solution 40 | ```{r} 41 | # 印出內建的 R 資料框 42 | mtcars 43 | ``` 44 | 45 | *** =sct 46 | ```{r} 47 | test_output_contains("mtcars", incorrect_msg = "不需要更改任何程式,確定你有將 `mtcars` 印出。") 48 | success_msg("太棒了,前進下一個練習!") 49 | ``` 50 | 51 | 52 | --- type:NormalExercise xp:100 skills:1 key:c3f245836ce0b7473355c0278265f0b16f18a4b7 53 | ## 很快地看看資料框 54 | 55 | 哇,資料中列出了很多不同的車行與它們的資訊! 56 | 57 | 你常常需要分析龐大的資料,你的第一件事應該是對資料結構與主要元素有清晰的認知,先觀察小部份的資料是很有用的。 58 | 59 | 在 R 中我們可以使用[`head()`](http://www.rdocumentation.org/packages/utils/functions/head)函數來展示資料框的前幾個觀測值,相同地,[`tail()`](http://www.rdocumentation.org/packages/utils/functions/head)函數則可以展示資料框的最終幾個觀測值。 60 | 61 | [`head()`](http://www.rdocumentation.org/packages/utils/functions/head)與[`tail()`](http://www.rdocumentation.org/packages/utils/functions/head)函數都會一併展示欄位名稱。 62 | 63 | *** =instructions 64 | 對[`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars)資料框使用[`head()`](http://www.rdocumentation.org/packages/utils/functions/head)函數來看看它的欄位名稱與前幾列觀測值。 65 | 66 | *** =hint 67 | `head(mtcars)` 會將 `mtcars` 的前幾列印出。 68 | 69 | *** =pre_exercise_code 70 | ```{r} 71 | # no pec 72 | ``` 73 | 74 | *** =sample_code 75 | ```{r} 76 | # 對 mtcars 呼叫 head() 77 | 78 | ``` 79 | 80 | *** =solution 81 | ```{r} 82 | # 對 mtcars 呼叫 head() 83 | head(mtcars) 84 | ``` 85 | 86 | *** =sct 87 | ```{r} 88 | test_function("head", "x", incorrect_msg = "確認是否有對 `mtcars` 使用 `head()` 函數?") 89 | test_output_contains("head(mtcars)", incorrect_msg = "只需要將呼叫 `head()` 的結果印出即可,不需要指派新變數。") 90 | success_msg("太棒了,讓我們看看 `mtcars` 資料集中哪些有資料,例如 `hp` 代表車子的馬力,且這 6 輛車子中馬力最低的為 Datsun710,在 R Console 輸入 `?mtcars` 可查閱詳細的變數定義與類型,前進下一個練習!"); 91 | ``` 92 | 93 | 94 | --- type:NormalExercise xp:100 skills:1 key:44c05f378266cbc25079ec804787fdc09e111aa0 95 | ## 觀察一下結構 96 | 97 | 另外一種常用來快速瞭解資料的方式為使用[`str()`](http://www.rdocumentation.org/packages/utils/functions/str)函數,[`str()`](http://www.rdocumentation.org/packages/utils/functions/str)函數顯示資料的結構,告訴我們下列資料框的資訊: 98 | 99 | - 觀測值的總數( 32 種車型) 100 | - 變數的總數( 11 種車輛資訊) 101 | - 變數名稱的清單(`mpg`, `cyl` ...) 102 | - 變數的資料類型(`數值`) 103 | - 前幾個觀測值 104 | 105 | 當你拿到一個新資料框,在你開始做分析之前通常會使用[`str()`](http://www.rdocumentation.org/packages/utils/functions/str)函數了解資料的樣態。 106 | 107 | *** =instructions 108 | 觀察[`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars)的結構,並確定你有觀察到跟前述相同的觀測值個數、變數總計與資料類別。 109 | 110 | *** =hint 111 | 對[`mtcars`](http://www.rdocumentation.org/packages/datasets/functions/mtcars)使用[`str()`](http://www.rdocumentation.org/packages/utils/functions/str)函數。 112 | 113 | *** =pre_exercise_code 114 | ```{r} 115 | # no pec 116 | ``` 117 | 118 | *** =sample_code 119 | ```{r} 120 | # 查看 mtcars 的結構 121 | ``` 122 | 123 | *** =solution 124 | ```{r} 125 | # 查看 mtcars 的結構 126 | str(mtcars) 127 | ``` 128 | 129 | *** =sct 130 | ```{r} 131 | test_output_contains("str(mtcars)", incorrect_msg = "確認是否有對 `mtcars` 使用 `str()`?") 132 | success_msg("作得好,你看到了說明中的資訊嗎?前進下一個練習!") 133 | ``` 134 | 135 | 136 | --- type:NormalExercise xp:100 skills:1 key:1599e175505f5980064369d4fea9b77ce1574b4e 137 | ## 建立一個資料框 138 | 139 | 用內建的資料框一點都不有趣對吧!接下來的練習我們要使用你自己建立的資料框,讓我們穿上太空衣,做一點星際探索吧! 140 | 141 | 首先,我們建立一個描述太陽系八個行星的資料框,我們的好朋友巴斯光年說星球的主要特性有: 142 | 143 | - 星球種類(陸地或氣體)。 144 | - 星球相對於地球的直徑。 145 | - 星球相對於地球的自轉頻率。 146 | - 星球是否有環(`TRUE` 或 `FALSE`)。 147 | 148 | 在維基百科 [Wikipedia](http://en.wikipedia.org/wiki/Planet) 上精細地研究後,我們很有自信地建立了 5 個向量: `name` 、 `type` 、 `diameter` 、 `rotation` 與 `rings`(建立這 5 個向量的程式已經寫好在編輯區中。) 149 | 150 | 使用[`data.frame()`](http://www.rdocumentation.org/packages/base/functions/data.frame)函數建立資料框,這 5 個向量將會成為資料框中的欄位,它們的長度都相等,但資料格式卻不盡相同。 151 | 152 | *** =instructions 153 | 使用[`data.frame()`](http://www.rdocumentation.org/packages/base/functions/data.frame)函數建立資料框,將`name` 、 `type` 、 `diameter` 、 `rotation` 與 `rings` 做為參數放入 `data.frame()`並將建立的資料框命名為 `planets_df`。 154 | 155 | *** =hint 156 | 你的`data.frame()`函數會長得類似像這樣: 157 | ``` 158 | data.frame(planets, type, diameter) 159 | ``` 160 | 你可以完成它嗎? 161 | 162 | *** =pre_exercise_code 163 | ```{r} 164 | # no pec 165 | ``` 166 | 167 | *** =sample_code 168 | ```{r} 169 | # 宣告向量 170 | name <- c("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune") 171 | type <- c("Terrestrial planet", "Terrestrial planet", "Terrestrial planet", 172 | "Terrestrial planet", "Gas giant", "Gas giant", "Gas giant", "Gas giant") 173 | diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883) 174 | rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67) 175 | rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE) 176 | 177 | # 由這些向量建立資料框 178 | planets_df <- 179 | 180 | ``` 181 | 182 | *** =solution 183 | ```{r} 184 | # 宣告向量 185 | name <- c("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune") 186 | type <- c("Terrestrial planet", "Terrestrial planet", "Terrestrial planet", 187 | "Terrestrial planet", "Gas giant", "Gas giant", "Gas giant", "Gas giant") 188 | diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883) 189 | rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67) 190 | rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE) 191 | 192 | # 由這些向量建立資料框 193 | planets_df <- data.frame(name, type, diameter, rotation, rings) 194 | ``` 195 | 196 | *** =sct 197 | ```{r} 198 | msg = "不需要更改向量的宣告,加入 `data.frame()` 建立 `planets_df`。" 199 | test_object("name", undefined_msg = msg, incorrect_msg = msg) 200 | test_object("type", undefined_msg = msg, incorrect_msg = msg) 201 | test_object("diameter", undefined_msg = msg, incorrect_msg = msg) 202 | test_object("rotation", undefined_msg = msg, incorrect_msg = msg) 203 | test_object("rings", undefined_msg = msg, incorrect_msg = msg) 204 | 205 | test_object("planets_df", 206 | incorrect_msg = "確認是否有使用 `data.frame()` 建立 `planets_df`,並確認在 `data.frame()` 函數中用正確的順序將所有的向量當作參數寫入: `name` 、 `type` 、 `diameter` 、 `rotation` 與 `rings`。") 207 | 208 | success_msg("作得好,前進下一個練習,接下來我們要檢視你剛建立好的資料框!"); 209 | ``` 210 | 211 | 212 | --- type:NormalExercise xp:100 skills:1 key:72d24b916b842527b40bd19ff3093b823980c234 213 | ## 建立一個資料框(2) 214 | 215 | `planets_df` 資料框已經載入至工作區,它有 8 個觀測值與 5 個欄位,你可以直接使用它。 216 | 217 | *** =instructions 218 | 使用[`str()`](http://www.rdocumentation.org/packages/utils/functions/str)函數來檢視 `planets_df` 的結構與變數。 219 | 220 | *** =hint 221 | `planets_df` 已經載入至工作區,直接於編輯區輸入 `str(planets_df)` 即可。 222 | 223 | *** =pre_exercise_code 224 | ```{r} 225 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 226 | ``` 227 | 228 | *** =sample_code 229 | ```{r} 230 | # 檢查 planets_df 的結構 231 | ``` 232 | 233 | *** =solution 234 | ```{r} 235 | # 檢查 planets_df 的結構 236 | str(planets_df) 237 | ``` 238 | 239 | *** =sct 240 | ```{r} 241 | msg = "不需要移除或覆寫已經載入至工作區的 `planets_df` 資料框!" 242 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 243 | test_output_contains("str(planets_df)", incorrect_msg = "確認是否有使用 `str()` 來顯示 `planets_df` 的結構?") 244 | success_msg("太棒了,你現在對 `planets_df` 有清楚的了解,接下來的練習將讓你學會如何從資料框中選擇元素!") 245 | ``` 246 | 247 | 248 | --- type:NormalExercise xp:100 skills:1 key:a6eeec0beaa5b270c1e9fd1fd4bf285ac5363e1a 249 | ## 從資料框中選擇元素 250 | 251 | 與向量及矩陣相似,你可以使用中括號 `[ ]` 從資料框中選擇,並用逗號分別指定要選擇的列與欄,例如: 252 | 253 | - `my_df[1,2]` 將 `my_df` 第一列第二欄的元素選出。 254 | - `my_df[1:3,2:4]` 將 `my_df` 第一到三列與第二至四欄選出。 255 | 256 | 有時候想選出整列或整欄的所有元素,例如使用 `my_df[1, ]` 將會把第一列所有的元素選出。接下來我們將利用 `planets_df` 練習這些技巧! 257 | 258 | *** =instructions 259 | - 從 `planets_df` 的第一列第三欄將水星的直徑選出,並印出結果。 260 | - 從 `planets_df` 的第四列將火星所有的資訊選出,並印出結果。 261 | 262 | *** =hint 263 | 利用 `planets_df[2,3]` 可以將金星的直徑選出,如果是水星呢? 264 | 265 | *** =pre_exercise_code 266 | ```{r} 267 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 268 | ``` 269 | 270 | *** =sample_code 271 | ```{r} 272 | # planets_df 資料框已經預先載入 273 | 274 | # 印出水星的直徑(第一列第三欄) 275 | 276 | 277 | # 印出火星的資訊(第四列) 278 | 279 | ``` 280 | 281 | *** =solution 282 | ```{r} 283 | # planets_df 資料框已經預先載入 284 | 285 | # 印出水星的直徑(第一列第三欄) 286 | planets_df[1, 3] 287 | 288 | # 印出火星的資訊(第四列) 289 | planets_df[4, ] 290 | ``` 291 | 292 | *** =sct 293 | ```{r} 294 | msg = "不需要更改或覆寫 `planets_df` 資料框。" 295 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 296 | test_output_contains("planets_df[1,3]", incorrect_msg = "確認你是否有利用 `[1,3]` 選擇並印出水星的直徑?") 297 | test_output_contains("planets_df[4, ]", incorrect_msg = "確認你是否有利用 `[4,]` 選擇並印出火星的所有資訊?") 298 | success_msg("太棒了,除了用索引值以外,你也可以用欄位名稱從資料框中選出元素,前進下一個練習!") 299 | ``` 300 | 301 | 302 | --- type:NormalExercise xp:100 skills:1 key:1b1be7e1473994d9d6762816f15ea282787be250 303 | ## 從資料框中選擇元素(2) 304 | 305 | 除了使用索引值從資料框中選擇元素,你也可以使用變數名稱進行選擇。 306 | 307 | 如果你想選擇 `type` 欄位的前三個元素,你可以這樣做 308 | 309 | ``` 310 | planets_df[1:3,1] 311 | ``` 312 | 313 | 上述做法有一個缺點,就是必須先知道 `type` 位於資料框中第幾個欄位,然而,當資料框的欄位很多時,這種做法就顯得很困難,這時使用變數名稱會相對輕鬆許多: 314 | 315 | ``` 316 | planets_df[1:3,"type"] 317 | ``` 318 | 319 | *** =instructions 320 | 從 `planets_df` 中選擇並印出 `"diameter"` 的前 5 個觀測值。 321 | 322 | *** =hint 323 | 你可以使用 `planets_df[1:5, ...]` 選出前 5 個觀測值,將 `...` 替換成 `"diameter"` 這個欄位。 324 | 325 | *** =pre_exercise_code 326 | ```{r} 327 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 328 | ``` 329 | 330 | *** =sample_code 331 | ```{r} 332 | # planets_df 資料框已經預先載入 333 | 334 | # 選出 diameter 欄位的前 5 個值 335 | 336 | ``` 337 | 338 | *** =solution 339 | ```{r} 340 | # planets_df 資料框已經預先載入 341 | 342 | # 選出 diameter 欄位的前 5 個值 343 | planets_df[1:5, "diameter"] 344 | ``` 345 | 346 | *** =sct 347 | ```{r} 348 | msg = "不需要移除或覆寫 `planets_df` 資料框。" 349 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 350 | test_output_contains("planets_df[1:5, \"diameter\"]", incorrect_msg = "確認是否有利用 `[1:5, \"diameter\"]` 選出直徑欄位的前5個數值並印出來?") 351 | success_msg("太好了,前進下一個練習!") 352 | ``` 353 | 354 | 355 | --- type:NormalExercise xp:100 skills:1 key:c332cd7e7e46daa391edea8aea961414c8c8d0ce 356 | ## 有環的星球 357 | 358 | 你常常需要選出資料框中的某個特定欄位,假如要選出 `diameter` 變數,用以下兩列指令都可以: 359 | 360 | ``` 361 | planets_df[,3] 362 | planets_df[,"diameter"] 363 | ``` 364 | 365 | 其實資料框還有使用 `$` 符號的簡便方法: 366 | 367 | ``` 368 | planets_df$diameter 369 | ``` 370 | 371 | *** =instructions 372 | - 使用 `$` 符號把變數 `rings` 從 `planets_df` 選擇出來並指派給 `rings_vector`。 373 | - 印出 `rings_vector` 看看有沒有做對。 374 | 375 | *** =hint 376 | 使用 `planets_df$diameter` 可以將 `diameter` 欄位從 `planets_df` 中選出,那麼應該如何將 `rings` 欄位選出呢? 377 | 378 | *** =pre_exercise_code 379 | ```{r} 380 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 381 | ``` 382 | 383 | *** =sample_code 384 | ```{r} 385 | # planets_df 資料框已經預先載入 386 | 387 | # 從 planets_df 選出變數 rings 388 | rings_vector <- 389 | 390 | # 印出 rings_vector 391 | ``` 392 | 393 | *** =solution 394 | ```{r} 395 | # planets_df 資料框已經預先載入 396 | 397 | # 從 planets_df 選出變數 rings 398 | rings_vector <- planets_df$rings 399 | 400 | # 印出 rings_vector 401 | rings_vector 402 | ``` 403 | 404 | *** =sct 405 | ```{r} 406 | msg = "不需要更改或覆寫 `planets_df` 資料框。" 407 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 408 | test_object("rings_vector", 409 | incorrect_msg = "確認是否利用 `$rings` 將變數 `rings` 從 `planets_df` 中選出並指派給 `rings_vector`。") 410 | test_output_contains("rings_vector", incorrect_msg = "別忘了在建立向量後將 `rings_vector` 印出!") 411 | success_msg("太好了,前進下一個練習並學習另外一個選擇元素的方式!") 412 | ``` 413 | 414 | 415 | --- type:NormalExercise xp:100 skills:1 key:0aa1fd7d080afe1bb1031562e8004121943632c6 416 | ## 有環的星球(2) 417 | 418 | 回憶一下高中教材,你可能記得太陽系中某些行星有環而某些沒有,但你大概想不起它們的名稱,更別說自轉頻率...等了。 419 | 420 | R 可以幫助你辦到嗎? 421 | 422 | 在 R Console 輸入 `rings_vector` 你可以得到: 423 | 424 | ``` 425 | [1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE 426 | ``` 427 | 428 | 上面結果顯示前四個觀測值(即前四個星球)沒有環(`FALSE`),但另外四個有環(`TRUE`),讓我們利用 `rings_vector` 將有環的四個星球選出來。 429 | 430 | *** =instructions 431 | 右方編輯區的程式將有環的星球名稱選出,修改程式改為將有環的星球_所有_欄位都選出。 432 | 433 | *** =hint 434 | 記得利用 `[rings_vector, ]` 選出_所有_欄位,將欄位的部分留白就可以。 435 | 436 | *** =pre_exercise_code 437 | ```{r} 438 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 439 | rings_vector <- planets_df$rings 440 | ``` 441 | 442 | *** =sample_code 443 | ```{r} 444 | # planets_df 與 rings_vector 已經預先載入 445 | 446 | # 修改程式選擇有環星球的所有欄位 447 | planets_df[rings_vector, "name"] 448 | ``` 449 | 450 | *** =solution 451 | ```{r} 452 | # planets_df 與 rings_vector 已經預先載入 453 | 454 | # 修改程式選擇有環星球的所有欄位 455 | planets_df[rings_vector, ] 456 | ``` 457 | 458 | *** =sct 459 | ```{r} 460 | msg <- "不需要移除或覆寫 `planets_df` 或 `rings_vector`。" 461 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 462 | test_object("rings_vector", undefined_msg = msg, incorrect_msg = msg) 463 | test_output_contains('planets_df[rings_vector, ]', incorrect_msg = "確認是否有使用 `planets_df[rings_vector, ]` 選出有環星球的_所有_欄位?逗號很重要,不要忘記了!") 464 | success_msg("太棒了,這個解法有點麻煩,下一個練習會教你一個更簡潔的方式!") 465 | ``` 466 | 467 | 468 | --- type:NormalExercise xp:100 skills:1 key:9b873ed27e9df18a217699041950ecd20691eaf1 469 | ## 有環的星球但簡單些 470 | 471 | 想想在前一個練習中學會了什麼?你根據有環或者沒有環從 `planets_df` 中選出了資料框子集,這真的超強的,也許美國太空總署已經在偷偷討論要招募你了喔! 472 | 473 | 讓我們來認識一個更高明的[`subset()`](http://www.rdocumentation.org/packages/base/functions/subset)函數,[`subset()`](http://www.rdocumentation.org/packages/base/functions/subset)函數可以更快速地做到前面練習所做到的事情。 474 | 475 | ``` 476 | subset(my_df, subset = some_condition) 477 | ``` 478 | 479 | [`subset()`](http://www.rdocumentation.org/packages/base/functions/subset)函數中的第一個參數指定了要被篩選的資料,第二個參數則要告訴 R 篩選的邏輯為何。 480 | 481 | 以下的程式會得到跟前一個練習一樣的結果,但這次你不需要另外宣告 `rings_vector`。 482 | 483 | ``` 484 | subset(planets_df, subset = rings) 485 | ``` 486 | 487 | *** =instructions 488 | 對 `planets_df` 使用 `subset()` 將直徑比地球小的星球選出來,由於直徑是個相對量值,你的條件應該要下 `diameter < 1`。 489 | 490 | *** =hint 491 | 稍微修改一下 `subset(planets_df, subset = ...)` 將 `...` 改為? 492 | 493 | *** =pre_exercise_code 494 | ```{r} 495 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 496 | ``` 497 | 498 | *** =sample_code 499 | ```{r} 500 | # planets_df 資料框已經預先載入 501 | 502 | # 選出直徑 <1 的星球 503 | 504 | ``` 505 | 506 | *** =solution 507 | ```{r} 508 | # planets_df 資料框已經預先載入 509 | 510 | # 選出直徑 <1 的星球 511 | subset(planets_df, subset = diameter < 1) 512 | ``` 513 | 514 | *** =sct 515 | ```{r} 516 | msg = "不需要移除或覆寫 `planets_df` 資料框。" 517 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 518 | test_correct({ 519 | test_output_contains("subset(planets_df, subset = diameter < 1)", incorrect_msg = "確認是否有在 `subset()` 函數中正確指派參數 `subset = ...`。條件應該要下 `diameter < 1` 並將結果印出。") 520 | }, { 521 | test_function("subset", args = "x", 522 | not_called_msg = "確認是否有使用 `subset()` 函數?", 523 | incorrect_msg = " `subset()` 函數中的第一個參數應該為 `planets_df`。") 524 | }) 525 | success_msg("太棒了, `subset()` 不僅很簡潔,它也能夠讓讀者更了解你的程式,前進下一個練習!"); 526 | ``` 527 | 528 | 529 | --- type:NormalExercise xp:100 skills:1 key:2397d0f7cdf728961c9f5b8208c3b2694e20e2df 530 | ## 排序 531 | 532 | 人們總是很喜歡排名,像是世界上最好的大學、最有影響力的電影明星或者最像 007 情報員的人。 533 | 534 | 在 R 中使用[`order()`](http://www.rdocumentation.org/packages/base/functions/order)函數可以讓我們依照某個欄位排序資料框的觀測值。 535 | 536 | [`order()`](http://www.rdocumentation.org/packages/base/functions/order)函數會回傳投入變數的排序順位,例如: 537 | 538 | ``` 539 | > a <- c(100, 10, 1000) 540 | > order(a) 541 | [1] 2 1 3 542 | ``` 543 | 544 | 10 是最小的元素,所以回傳結果的第二個元素為 1,而 100 是第二小的元素,故回傳結果的第一個元素為 2。 545 | 546 | 這表示我們可以利用 `order(a)` 的輸出重新排序 `a` 的順序: 547 | 548 | ``` 549 | > a[order(a)] 550 | [1] 10 100 1000 551 | ``` 552 | 553 | *** =instructions 554 | 在 R Console 體驗一下[`order()`](http://www.rdocumentation.org/packages/base/functions/order)函數,準備好後按下 Submit Answer。 555 | 556 | *** =hint 557 | 在 R Console 中體驗一下[`order()`](http://www.rdocumentation.org/packages/base/functions/order)函數! 558 | 559 | *** =pre_exercise_code 560 | ```{r} 561 | # no pec 562 | ``` 563 | 564 | *** =sample_code 565 | ```{r} 566 | # 在 R Console 中試用 order 函數,或直接按 Submit Answer 即可 567 | ``` 568 | 569 | *** =solution 570 | ```{r} 571 | # 在 R Console 中試用 order 函數,或直接按 Submit Answer 即可 572 | ``` 573 | 574 | *** =sct 575 | ```{r} 576 | success_msg("太棒了,讓我們來使用 `order()` 函數來排序你的資料框!") 577 | ``` 578 | 579 | 580 | --- type:NormalExercise xp:100 skills:1 key:81baabbbb256ac67de6d584ee37cfa218566f54a 581 | ## 排序你的資料框 582 | 583 | 現在你了解[`order()`](http://www.rdocumentation.org/packages/base/functions/order)函數,接下來你可以依據 `diameter` 欄位排序資料框,從最小的星球排到最大的星球。 584 | 585 | *** =instructions 586 | - 對 `planets_df$diameter` (`planets_df` 的 `diameter`欄位) 使用 `order()` 並將結果存為 `positions`。 587 | - 利用 `positions` 向量作為中括號裡的列數索引重洗 `planets_df` ,保留所有的欄位並將結果印出。 588 | 589 | *** =hint 590 | - 利用 `order(planets_df$diameter)` 建立 `positions`。 591 | - 在中括號中使用 `positions` 例如 `planets_df[...]` ,你知道在 `...` 中該填什麼? 592 | 593 | *** =pre_exercise_code 594 | ```{r} 595 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/planets.RData")) 596 | ``` 597 | 598 | *** =sample_code 599 | ```{r} 600 | # planets_df 已經預先載入 601 | 602 | # 使用 order() 建立 positions 603 | positions <- 604 | 605 | # 使用 positions 排序 planets_df 606 | 607 | ``` 608 | 609 | *** =solution 610 | ```{r} 611 | # planets_df 已經預先載入 612 | 613 | # 使用 order() 建立 positions 614 | positions <- order(planets_df$diameter) 615 | 616 | # 使用 positions 排序 planets_df 617 | planets_df[positions, ] 618 | ``` 619 | 620 | *** =sct 621 | ```{r} 622 | msg = "不需要移除或覆寫 `planets_df` 資料框!" 623 | test_object("planets_df", undefined_msg = msg, incorrect_msg = msg) 624 | test_object("positions", 625 | incorrect_msg = "確認是否使用 `sort(planets_df$diameter)` 正確計算 `positions`?") 626 | test_output_contains("planets_df[positions,]", 627 | incorrect_msg = "使用 `planets_df[positions, ]` 來排序 `planets_df` ,中括號裡的逗號很重要!") 628 | success_msg("太完美了,這是資料框的最後一個練習,記得資料框在 R 中是非常重要的,未來你將很常碰到它,另外一個常見的資料格式是清單,是我們下一章要學習的主題!") 629 | ``` 630 | 631 | 632 | -------------------------------------------------------------------------------- /chapter3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : 第三章 3 | title : 矩陣 4 | description : 在本章節我們將學習如何在 R 使用矩陣,包括宣告以及運算,我們將要使用矩陣來分析星際大戰的票房記錄,願原力與我們同在! 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:61a40bda779e572e5cc17be23357c98bceb73943 7 | ## 矩陣是什麼? 8 | 9 | 矩陣是一種將相同資料類別(數值、文字或邏輯值)排序在列與欄的資料型態,因為有列與欄,所以矩陣具有二個維度。 10 | 11 | 你可以使用[`matrix()`](http://www.rdocumentation.org/packages/base/functions/matrix)函數創造一個矩陣,例如: 12 | 13 | ``` 14 | matrix(1:9, byrow = TRUE, nrow = 3) 15 | ``` 16 | 17 | 在[`matrix()`](http://www.rdocumentation.org/packages/base/functions/matrix)函數中: 18 | 19 | - 第一個參數為要放進矩陣的元素,`1:9` 為 `c(1, 2, 3, 4, 5, 6, 7, 8, 9)` 的簡單寫法。 20 | - 第二個參數 `byrow` 表示在填滿矩陣時是以列的方向放入元素;如果希望以欄的方向填滿,需調整為 `byrow = FALSE`。 21 | - 第三個參數 `nrow` 表示矩陣有3列。 22 | 23 | *** =instructions 24 | 宣告一個具有 3 列的矩陣並以**列**的方向將 1 到 9 填入,記得要指定 `byrow = TRUE` 。 25 | 26 | *** =hint 27 | 再詳讀一次說明,答案其實已經很明顯了! 28 | 29 | *** =pre_exercise_code 30 | ```{r} 31 | # no pec 32 | ``` 33 | 34 | *** =sample_code 35 | ```{r} 36 | # 宣告一個具有 3 列的矩陣,且將數值 1:9 依序以列的方向填入此矩陣 37 | ``` 38 | 39 | *** =solution 40 | ```{r} 41 | # 宣告一個具有 3 列的矩陣,且將數值 1: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 = "請確認是否正確地宣告矩陣?再詳讀一次說明,答案其實已經很明顯了!") 49 | test_output_contains("matrix(1:9, byrow=TRUE, nrow=3)", 50 | incorrect_msg = "看起來矩陣的宣告有問題,再詳讀一次說明,答案其實已經很明顯了!") 51 | success_msg("好棒,前進下一個練習!") 52 | ``` 53 | 54 | 55 | --- type:NormalExercise xp:100 skills:1 key:befa6552ba5318e95e3c954443aa6ec643d1827f 56 | ## 分析矩陣 57 | 58 | 該是捲起袖子來寫程式的時候了,在接下來的練習中你要分析星際大戰首映票房記錄,願原力與你同在! 59 | 60 | 編輯區已經宣告好 3 個向量,分別代表著前三部星際大戰電影(曙光乍現、帝國大反擊與絕地大反攻)的票房收入,其中每個向量的第一個元素代表美國票房收入,第二個元素代表非美國票房收入(資料來源:維基百科)。 61 | 62 | 在這個練習中你要合併這三個向量然後建立一個矩陣。 63 | 64 | *** =instructions 65 | - 利用 `c(new_hope, empire_strikes, return_jedi)` 合併這三個向量並指派給一個新向量 `box_office`。 66 | - 使用 `matrix()` 函數建立一個擁有 3 列的矩陣,每一列都代表一部電影,第一個參數為 `box_office` 它包含所有票房收入記錄,第二個與第三個參數你要指定 `nrow = 3` 以及 `byrow = TRUE`。命名這個新建立的矩陣為 `star_wars_matrix`。 67 | 68 | *** =hint 69 | - `box_office <- c(new_hope, empire_strikes, return_jedi)` 可以合併成一個有 6 個元素的向量。 70 | - `matrix(box_office, nrow = ..., by_row = ...)` 是建立矩陣的函數架構。 71 | 72 | *** =pre_exercise_code 73 | ```{r} 74 | # no pec 75 | ``` 76 | 77 | *** =sample_code 78 | ```{r} 79 | # 星際大戰票房(百萬元美金!) 80 | new_hope <- c(460.998, 314.4) 81 | empire_strikes <- c(290.475, 247.900) 82 | return_jedi <- c(309.306, 165.8) 83 | 84 | # 宣告 box_office 85 | box_office <- 86 | 87 | # 建立 star_wars_matrix 88 | star_wars_matrix <- 89 | ``` 90 | 91 | *** =solution 92 | ```{r} 93 | # 星際大戰票房(百萬元美金!) 94 | new_hope <- c(460.998, 314.4) 95 | empire_strikes <- c(290.475, 247.900) 96 | return_jedi <- c(309.306, 165.8) 97 | 98 | # 宣告 box_office 99 | box_office <- c(new_hope, empire_strikes, return_jedi) 100 | 101 | # 建立 star_wars_matrix 102 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE) 103 | ``` 104 | 105 | *** =sct 106 | ```{r} 107 | msg <- "不需要更改 `new_hope` 、 `empire_strikes` 與 `return_jedi`。" 108 | test_object("new_hope", undefined_msg = msg, incorrect_msg = msg) 109 | test_object("empire_strikes", undefined_msg = msg, incorrect_msg = msg) 110 | test_object("return_jedi", undefined_msg = msg, incorrect_msg = msg) 111 | 112 | test_object("box_office", incorrect_msg = "請確認是否正確合併 `new_hope` 、 `empire_strikes` 與 `return_jedi` 成為 `box_office`?") 113 | 114 | test_function("matrix", c("data", "nrow", "byrow"), 115 | incorrect_msg = "請確認 `matrix()` 的參數: `box_office` 、 `nrow = 3` 、 `by_row = TRUE`。") 116 | 117 | test_object("star_wars_matrix", 118 | incorrect_msg = "請確認是否指派 `matrix()` 的結果給 `star_wars_matrix`?") 119 | 120 | success_msg("原力真的與你同在,前進下一個練習!") 121 | ``` 122 | 123 | 124 | --- type:NormalExercise xp:100 skills:1 key:37aed0b157460a60af201e3dc57142bbbf187c71 125 | ## 為矩陣命名 126 | 127 | 為了記住 `star_wars_matrix` 中儲存的資料,你打算為列與欄命名。 128 | 129 | ``` 130 | rownames(my_matrix) <- row_names_vector 131 | colnames(my_matrix) <- col_names_vector 132 | ``` 133 | 134 | 我們準備了 2 個向量 `region` 與 `titles` 。你會需要用這兩個向量來分別為 `star_wars_matrix` 的列與欄命名。 135 | 136 | *** =instructions 137 | - 使用 `colnames()` 將 `region` 指派給 `star_wars_matrix` 的欄名稱。 138 | - 使用 `rownames()` 將 `titles` 指派給 `star_wars_matrix` 的列名稱。 139 | - 印出 `star_wars_matrix` 看結果。 140 | 141 | *** =hint 142 | 你可以使用 `colnames(star_wars_matrix) <- region` 來為 `star_wars_matrix` 命名,列的命名也很類似。 143 | 144 | *** =pre_exercise_code 145 | ```{r} 146 | # no pec 147 | ``` 148 | 149 | *** =sample_code 150 | ```{r} 151 | # 星際大戰票房(百萬元美金!) 152 | new_hope <- c(460.998, 314.4) 153 | empire_strikes <- c(290.475, 247.900) 154 | return_jedi <- c(309.306, 165.8) 155 | 156 | # 建立 star_wars_matrix 157 | star_wars_matrix <- matrix(c(new_hope, empire_strikes, return_jedi), nrow = 3, byrow = TRUE) 158 | 159 | # 用來命名的向量 region 與 titles 160 | region <- c("US", "non-US") 161 | titles <- c("A New Hope", "The Empire Strikes Back", "Return of the Jedi") 162 | 163 | # 用 region 為欄命名 164 | 165 | 166 | # 用 titles 為列命名 167 | 168 | 169 | # 印出 star_wars_matrix 170 | ``` 171 | 172 | *** =solution 173 | ```{r} 174 | # 星際大戰票房(百萬元美金!) 175 | new_hope <- c(460.998, 314.4) 176 | empire_strikes <- c(290.475, 247.900) 177 | return_jedi <- c(309.306, 165.8) 178 | 179 | # 建立 star_wars_matrix 180 | star_wars_matrix <- matrix(c(new_hope, empire_strikes, return_jedi), nrow = 3, byrow = TRUE) 181 | 182 | # 用來命名的向量 region 與 titles 183 | region <- c("US", "non-US") 184 | titles <- c("A New Hope", "The Empire Strikes Back", "Return of the Jedi") 185 | 186 | # 用 region 為欄命名 187 | colnames(star_wars_matrix) <- region 188 | 189 | # 用 titles 為列命名 190 | rownames(star_wars_matrix) <- titles 191 | 192 | # 印出 star_wars_matrix 193 | star_wars_matrix 194 | ``` 195 | 196 | *** =sct 197 | ```{r} 198 | msg <- "不需要更改 `new_hope` 、 `empire_strikes` 與 `return_jedi`。" 199 | test_object("new_hope", undefined_msg = msg, incorrect_msg = msg) 200 | test_object("empire_strikes", undefined_msg = msg, incorrect_msg = msg) 201 | test_object("return_jedi", undefined_msg = msg, incorrect_msg = msg) 202 | msg <- "不需要更改 `star_wars_matrix` ,只要幫列與欄命名。" 203 | test_object("star_wars_matrix", incorrect_msg = msg) 204 | msg <- "不需要更改 `region` 與 `titles` 這2個已經幫你定義好的向量。" 205 | test_object("region", undefined_msg = msg, incorrect_msg = msg) 206 | test_object("titles", undefined_msg = msg, incorrect_msg = msg) 207 | test_object("star_wars_matrix", eq_condition = "equal", 208 | incorrect_msg = "請確認是否有正確命名 `star_wars_matrix` 的列與欄? 使用 `colnames(star_wars_matrix) <- region` 為欄命名,用同樣方法對列命名。") 209 | test_output_contains("star_wars_matrix", incorrect_msg = "別忘了要把 `star_wars_matrix` 印出來看看。") 210 | success_msg("太棒了,你正在成為一個 R 絕地武士,前進下一個練習!") 211 | ``` 212 | 213 | 214 | --- type:NormalExercise xp:100 skills:1 key:99052c568114e85002519d338103ed0c8521ce61 215 | ## 計算全球票房 216 | 217 | 全球票房收入是在好萊塢成為傳奇電影的首要條件。 218 | 219 | 你必須知道如何把美國票房收入與非美國票房收入相加才能計算這三部星際大戰電影的全球票房收入。 220 | 221 | R的[`rowSums()`](http://www.rdocumentation.org/packages/base/functions/colSums)函數可以方便你計算矩陣中每一列的總和,它會產生一個新的向量: 222 | 223 | ``` 224 | rowSums(my_matrix) 225 | ``` 226 | 227 | *** =instructions 228 | 計算三部電影的全球票房收入並指派給向量 `worldwide_vector`。 229 | 230 | *** =hint 231 | `rowSums(star_wars_matrix)` 可以計算矩陣每一列的總和,即每一部電影的全球票房收入。 232 | 233 | *** =pre_exercise_code 234 | ```{r} 235 | # no pec 236 | ``` 237 | 238 | *** =sample_code 239 | ```{r} 240 | # 建立 star_wars_matrix 241 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 242 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 243 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 244 | c("US", "non-US"))) 245 | 246 | # 計算全球票房收入 247 | worldwide_vector <- 248 | ``` 249 | 250 | *** =solution 251 | ```{r} 252 | # 建立 star_wars_matrix 253 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 254 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 255 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 256 | c("US", "non-US"))) 257 | 258 | # 計算全球票房收入 259 | worldwide_vector <- rowSums(star_wars_matrix) 260 | ``` 261 | 262 | *** =sct 263 | ```{r} 264 | msg <- "不需要更改 `box_office_all` 與 `star_wars_marix`。" 265 | test_object("box_office", undefined_msg = msg, incorrect_msg = msg) 266 | test_object("star_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 267 | test_object("worldwide_vector", incorrect_msg = "對 `star_wars_matrix` 使用 `rowSums()` 函數並將結果指派給 `worldwide_vector`。") 268 | success_msg("作得好,前進下一個練習!") 269 | ``` 270 | 271 | 272 | --- type:NormalExercise xp:100 skills:1 key:b3920821c2964147c5db451c4d66c8e6172dfda4 273 | ## 再多加一欄 274 | 275 | 前一個練習中,我們已計算出 3 部星際大戰電影的全球票房收入,但是結果並未合併至 `star_wars_matrix` 中。 276 | 277 | 使用[`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind)函數來增加矩陣的欄位,例如這段程式可以結合 matrix1 、 matrix2 與 vector1 成為一個 big_matrix: 278 | 279 | ``` 280 | big_matrix <- cbind(matrix1, matrix2, vector1 ...) 281 | ``` 282 | 283 | *** =instructions 284 | 使用[`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind)函數加入 `worldwide_vector` 做為 `star_wars_matrix` 中新的一欄,並將結果指派給 `all_wars_matrix`。 285 | 286 | *** =hint 287 | 將矩陣 `star_wars_matrix` 與向量 `worldwide_vector` 做為 `cbind()` 的 2 個參數然後指派給 `all_wars_matrix`。 288 | 289 | *** =pre_exercise_code 290 | ```{r} 291 | # no pec 292 | ``` 293 | 294 | *** =sample_code 295 | ```{r} 296 | # 建立 star_wars_matrix 297 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 298 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 299 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 300 | c("US", "non-US"))) 301 | 302 | # 計算全球票房收入 303 | worldwide_vector <- rowSums(star_wars_matrix) 304 | 305 | # 將 worldwide_vector 加入 star_wars_matrix 306 | all_wars_matrix <- 307 | ``` 308 | 309 | *** =solution 310 | ```{r} 311 | # 建立 star_wars_matrix 312 | box_office <- c(460.998, 314.4, 290.475, 247.900, 309.306, 165.8) 313 | star_wars_matrix <- matrix(box_office, nrow = 3, byrow = TRUE, 314 | dimnames = list(c("A New Hope", "The Empire Strikes Back", "Return of the Jedi"), 315 | c("US", "non-US"))) 316 | 317 | # 計算全球票房收入 318 | worldwide_vector <- rowSums(star_wars_matrix) 319 | 320 | # 將 worldwide_vector 加入 star_wars_matrix 321 | all_wars_matrix <- cbind(star_wars_matrix, worldwide_vector) 322 | ``` 323 | 324 | *** =sct 325 | ```{r} 326 | msg <- "不需要更改 `box_office_all` 與 `star_wars_marix`。" 327 | test_object("box_office", undefined_msg = msg, incorrect_msg = msg) 328 | test_object("star_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 329 | test_object("worldwide_vector", 330 | incorrect_msg = "將 `rowSums(star_wars_matrix)` 的結果儲存在 `worldwide_vector` 中。") 331 | 332 | # TODO: Fix in testwhat 333 | msg <- "確認是否正確使用 `cbind()` 來合併 `worldwide_vector` 與 `star_wars_matrix`?你應該依序將 `star_wars_matrix` 與 `world_wide_vector` 作為 `cbind()` 的兩個參數,如此一來 `all_wars_matrix` 將有三列與三欄。" 334 | test_object("all_wars_matrix", incorrect_msg = msg) 335 | success_msg("作得好,接下來我們來試著加列,前進下一個練習!"); 336 | ``` 337 | 338 | 339 | --- type:NormalExercise xp:100 skills:1 key:31368f587442b9db1b8836534e6998b0d024835e 340 | ## 新增一列 341 | 342 | 就如同作用力與反作用力,有[`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind)自然也會有[`rbind()`](http://www.rdocumentation.org/packages/base/functions/cbind)(我們實在不太會用譬喻法。) 343 | 344 | 在 R 工作區已經宣告好兩個矩陣([工作區是什麼](http://www.statmethods.net/interface/workspace.html)): 345 | 346 | - 我們一直在使用的第一個三部曲電影矩陣 `star_wars_matrix`。 347 | - 第二個三部曲電影矩陣 `star_wars_matrix2`。 348 | 349 | 在 R Console 輸入 `ls()` 可以檢視工作區的內容,輸入已經宣告好的 2 個矩陣可以看到內容。 350 | 351 | *** =instructions 352 | 用 `rbind()` 把 `star_wars_matrix` 和 `star_wars_matrix2` 合併並將結果指派給 `all_wars_matrix` 之後,把 `all_wars_matrix` 印出來。 353 | 354 | *** =hint 355 | 合併兩個矩陣: 356 | ``` 357 | rbind(matrix1, matrix2) 358 | ``` 359 | 把結果指派給 `all_wars_matrix` 並印出來。 360 | 361 | 362 | *** =pre_exercise_code 363 | ```{r} 364 | # 建立 star_wars_matrix 365 | box_office_all <- c(461, 314.4, 290.5, 247.9, 309.3, 165.8) 366 | movie_names <- c("A New Hope","The Empire Strikes Back","Return of the Jedi") 367 | col_titles <- c("US","non-US") 368 | star_wars_matrix <- matrix(box_office_all, nrow = 3, byrow = TRUE, dimnames = list(movie_names, col_titles)) 369 | 370 | # 建立 star_wars_matrix2 371 | box_office_all2 <- c(474.5, 552.5, 310.7, 338.7, 380.3, 468.5) 372 | movie_names2 <- c("The Phantom Menace", "Attack of the Clones", "Revenge of the Sith") 373 | star_wars_matrix2 <- matrix(box_office_all2, nrow=3, byrow = TRUE, dimnames = list(movie_names2, col_titles)) 374 | 375 | # 移除所有物件只留下 all_wars_matrix 376 | rm(box_office_all) 377 | rm(movie_names) 378 | rm(col_titles) 379 | rm(box_office_all2) 380 | rm(movie_names2) 381 | ``` 382 | 383 | *** =sample_code 384 | ```{r} 385 | # star_wars_matrix 與 star_wars_matrix2 已經存在於工作區中 386 | star_wars_matrix 387 | star_wars_matrix2 388 | 389 | # 合併 2 個三部曲 390 | all_wars_matrix <- 391 | 392 | # 將 all_wars_matrix 印出來 393 | 394 | ``` 395 | 396 | *** =solution 397 | ```{r} 398 | # star_wars_matrix 與 star_wars_matrix2 已經存在於工作區中 399 | star_wars_matrix 400 | star_wars_matrix2 401 | 402 | # 合併 2 個三部曲 403 | all_wars_matrix <- rbind(star_wars_matrix, star_wars_matrix2) 404 | 405 | # 將 all_wars_matrix 印出來 406 | all_wars_matrix 407 | ``` 408 | 409 | *** =sct 410 | ```{r} 411 | msg = "不需要更改`star_wars_matrix` 與 `star_wars_matrix2`。" 412 | test_object("star_wars_matrix", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 413 | test_object("star_wars_matrix2", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 414 | test_output_contains("all_wars_matrix", incorrect_msg = "別忘記把 `all_wars_matrix` 印出來!") 415 | test_object("all_wars_matrix", incorrect_msg = "請確認是否正確使用 `rbind()` 創造 `all_wars_matrix()`? `rbind()` 應該要依序有2個參數: `star_wars_matrix` 與 `star_wars_matrix2`。") 416 | 417 | success_msg("太完美了,前進下一個練習並加入 `colSums()` 函數!") 418 | ``` 419 | 420 | 421 | --- type:NormalExercise xp:100 skills:1 key:7dfd6a4e59e15742efd72fee93321ec289165846 422 | ## 星際大戰六部曲票房總收入 423 | 424 | 如同[`cbind()`](http://www.rdocumentation.org/packages/base/functions/cbind)與[`rbind()`](http://www.rdocumentation.org/packages/base/functions/cbind),[`colSums()`](http://www.rdocumentation.org/packages/base/functions/colSums)也有對應的[`rowSums()`](http://www.rdocumentation.org/packages/base/functions/colSums)。R 工作區已經有你在前一個練習建立的 `all_wars_matrix`, 輸入 `all_wars_matrix` 看看,接著我們要計算六部曲的票房總收入。 425 | 426 | *** =instructions 427 | - 計算美國與非美國的票房總收入並指派給 `total_revenue_vector`,你可以使用[`colSums()`](http://www.rdocumentation.org/packages/base/functions/colSums)函數。 428 | - 印出 `total_revenue_vector` 看看結果。 429 | 430 | *** =hint 431 | 使用[`colSums()`](http://www.rdocumentation.org/packages/base/functions/colSums)函數function,以 `star_wars_matrix` 做為參數找出各區域票房收入。 432 | 433 | *** =pre_exercise_code 434 | ```{r} 435 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 436 | ``` 437 | 438 | *** =sample_code 439 | ```{r} 440 | # all_wars_matrix 已經存在於工作區中 441 | all_wars_matrix 442 | 443 | # 美國與非美國的票房收入 444 | total_revenue_vector <- 445 | 446 | # 印出 total_revenue_vector 447 | ``` 448 | 449 | *** =solution 450 | ```{r} 451 | # all_wars_matrix 已經存在於工作區中 452 | all_wars_matrix 453 | 454 | # 美國與非美國的票房收入 455 | total_revenue_vector <- colSums(all_wars_matrix) 456 | 457 | # 印出 total_revenue_vector 458 | total_revenue_vector 459 | ``` 460 | 461 | *** =sct 462 | ```{r} 463 | msg = "不需要更改工作區已建立好的 `all_wars_matrix`。" 464 | test_object("all_wars_matrix", eq_condition = "equal", undefined_msg = msg, incorrect_msg = msg) 465 | test_function("colSums", "x", incorrect_msg = "確認是否對all_wars_matrix使用 `colSums()` 函數?") 466 | test_object("total_revenue_vector", 467 | incorrect_msg = "確認是否將 `colSums(all_wars_matrix)` 指派給 `total_revenue_vector`?") 468 | test_output_contains("total_revenue_vector", incorrect_msg = "別忘記把 `total_revenue_vector` 印出來!") 469 | success_msg("太美了,前進下一個練習矩陣的選擇!") 470 | ``` 471 | 472 | 473 | --- type:NormalExercise xp:100 skills:1 key:3f713b0c9ff675bf457941041819813ad7a5c19d 474 | ## 選擇矩陣中的元素 475 | 476 | 矩陣與向量一樣,皆使用中括號 `[ ]` 來選擇當中的一個或多個元素,因為矩陣具有2個維度,我們需要使用逗號來區分所選擇的列與欄,例如: 477 | 478 | - `my_matrix[1,2]` 可選出位於矩陣中第一列與第二欄的元素。 479 | - `my_matrix[1:3,2:4]` 可選出矩陣中第一列至第三列與第二欄至第四欄的元素。 480 | 481 | 如果你希望選出列或欄的所有元素,就不需要在逗號前後加上數字,例如: 482 | 483 | - `my_matrix[,1]` 可以把第一欄所有元素選出。 484 | - `my_matrix[1,]` 可以把第一列所有元素選出。 485 | 486 | 讓我們繼續回到星際大戰,在前一個練習中 `all_wars_matrix` 已經存在於工作區中。 487 | 488 | *** =instructions 489 | - 把六部曲非美國的電影票房收入( `all_wars_matrix` 中第二欄所有的元素)指派給 `non_us_all`。 490 | - 對 `non_us_all` 使用 `mean()` 函數來計算非美國票房收入的平均值並簡單印出結果。 491 | - 從 `all_wars_matrix` 選出前兩集的非美國票房收入,並指派給 `non_us_some`。 492 | - 對 `non_us_some` 使用 `mean()` 函數計算平均值並印出。 493 | 494 | *** =hint 495 | 用 `my_matrix[,2]` 可以將 `my_matrix` 的第二欄中所有元素選出。 496 | 497 | *** =pre_exercise_code 498 | ```{r} 499 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 500 | ``` 501 | 502 | *** =sample_code 503 | ```{r} 504 | # all_wars_matrix 已經存在於工作區中 505 | all_wars_matrix 506 | 507 | # 選出全部電影的非美國票房收入 508 | non_us_all <- 509 | 510 | # 非美國票房平均收入 511 | 512 | 513 | # 選出前兩部電影的非美國票房收入 514 | non_us_some <- 515 | 516 | # 前兩部電影的非美國票房平均收入 517 | 518 | ``` 519 | 520 | *** =solution 521 | ```{r} 522 | # all_wars_matrix 已經存在於工作區中 523 | all_wars_matrix 524 | 525 | # 選出全部電影的非美國票房收入 526 | non_us_all <- all_wars_matrix[,2] 527 | 528 | # 非美國票房平均收入 529 | mean(non_us_all) 530 | 531 | # 選出前兩部電影的非美國票房收入 532 | non_us_some <- all_wars_matrix[1:2,2] 533 | 534 | # 前兩部電影的非美國票房平均收入 535 | mean(non_us_some) 536 | ``` 537 | 538 | *** =sct 539 | ```{r} 540 | msg = "不需要更改工作區已建立好的 `all_wars_matrix`。" 541 | test_object("all_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 542 | 543 | test_object("non_us_all", 544 | incorrect_msg = "請確認是否將 `all_wars_matrix` 的第二欄指派給 `non_us_all` ?你可以使用 `[, 2]` 辦到!") 545 | test_output_contains("mean(non_us_all)", 546 | incorrect_msg = "請確認是否使用 `mean(non_us_all)` 計算 `non_us_all` 的平均值並印出結果?") 547 | test_object("non_us_some", 548 | incorrect_msg = "請確認是否指派前2部電影的非美國票房收入給 `non_us_some` ?你可以使用 `[1:2,2]` 辦到!") 549 | test_output_contains("mean(non_us_some)", 550 | incorrect_msg = "請確認是否使用 `mean(non_us_some)` 計算 `non_us_some` 的平均值並印出結果?") 551 | success_msg("太厲害了,前進下一個練習!") 552 | ``` 553 | 554 | 555 | --- type:NormalExercise xp:100 skills:1 key:4859ff893aeb0e78190fbece8655b0a65b58a814 556 | ## 一點點矩陣數學運算 557 | 558 | 跟你在向量學到的相同,標準運算子 `+` 、 `-` 、 `/` 、 `*` 等等都可以用在矩陣計算。 559 | 560 | 例如 `2 * my_matrix` 表示將 `my_matrix` 中的每個元素乘以 2。 561 | 562 | 身為盧卡斯影業新聘雇的資料分析師,你想找出不同地理區的六部曲觀看人數。你已經建立好總票房收入的 `all_wars_matrix`,現在假設電影票價格為 5 元,將票房收入除以 5 就可以得到觀看人數。 563 | 564 | *** =instructions 565 | - 將 `all_wars_matrix` 除以 5 得到觀看人數(百萬人),指派結果給 `visitors`。 566 | - 印出 `visitors` 看看。 567 | 568 | *** =hint 569 | 觀看人數為 `all_wars_matrix` 除以 5。 570 | 571 | *** =pre_exercise_code 572 | ```{r} 573 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 574 | ``` 575 | 576 | *** =sample_code 577 | ```{r} 578 | # all_wars_matrix 已經存在於工作區中 579 | all_wars_matrix 580 | 581 | # 估計觀看人數 582 | visitors <- 583 | 584 | # 印出觀看人數 585 | 586 | ``` 587 | 588 | *** =solution 589 | ```{r} 590 | # all_wars_matrix 已經存在於工作區中 591 | all_wars_matrix 592 | 593 | # 估計觀看人數 594 | visitors <- all_wars_matrix / 5 595 | 596 | # 印出觀看人數 597 | visitors 598 | ``` 599 | 600 | *** =sct 601 | ```{r} 602 | msg = "不需要更改工作區已建立好的 `all_wars_matrix`。" 603 | test_object("all_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 604 | 605 | test_object("visitors", 606 | incorrect_msg = "看起來 `visitors` 不正確,將 `all_wars_matrix` 除以5並將結果指派給 `visitors`。") 607 | test_output_contains("visitors", incorrect_msg = "別忘了將 `visitors` 印出來看看。") 608 | success_msg("計算結果告訴你,星際大戰四部曲:曙光乍現光是在美國就有 9 千 2 百萬個觀看人數,很驚人對嗎?前進下一個練習!") 609 | ``` 610 | 611 | 612 | --- type:NormalExercise xp:100 skills:1 key:6c34c3c66d9f2d2996cb8288112f2e604feac8ab 613 | ## 一點點矩陣數學運算(2) 614 | 615 | 如同 `2 * my_matrix` 會將 `my_matrix` 中的每個元素都乘以 2, `my_matrix1 * my_matrix2` 則是將對應相同位置的元素作乘法運算。 616 | 617 | 老闆盧卡斯看了前一個練習的結果後指出電影票價其實是有隨著時間調漲,要求你利用 `ticket_prices_matrix` 中的票價資料(資料來源:imagination) 重做一次分析。 618 | 619 | _對於熟悉矩陣的使用者,須留意上述的運算並非標準矩陣運算子,標準矩陣運算子要使用 `%*%`。_ 620 | 621 | *** =instructions 622 | - `all_wars_matrix` 除以 `ticket_prices_matrix` 可以得到美國與非美國的六部曲觀看人數,將結果指派給 `visitors` 並印出結果。 623 | - 選擇 `visitors` 中代表美國觀看人數的第一欄資料指派給 `us_visitors`。 624 | - 計算美國的平均觀看人數並印出結果。 625 | 626 | *** =hint 627 | - 使用 `mean()` 函數計算。 628 | - 使用 `visitors[ ,1]` 來取出 `visitors` 的第一欄以得到美國的觀看人數。 629 | 630 | *** =pre_exercise_code 631 | ```{r} 632 | load(url("http://s3.amazonaws.com/assets.datacamp.com/course/intro_to_r/all_wars_matrix.RData")) 633 | 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") 634 | col_titles <- c("US","non-US") 635 | 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)) 636 | ``` 637 | 638 | *** =sample_code 639 | ```{r} 640 | # all_wars_matrix 與 ticket_prices_matrix 已建立於工作區 641 | all_wars_matrix 642 | ticket_prices_matrix 643 | 644 | # 估計觀看人數 645 | visitors <- 646 | 647 | # 印出估計觀看人數 648 | 649 | 650 | # 美國觀看人數 651 | us_visitors <- 652 | 653 | # 美國平均觀看人數 654 | 655 | ``` 656 | 657 | *** =solution 658 | ```{r} 659 | # all_wars_matrix 與 ticket_prices_matrix 已建立於工作區 660 | all_wars_matrix 661 | ticket_prices_matrix 662 | 663 | # 估計觀看人數 664 | visitors <- all_wars_matrix / ticket_prices_matrix 665 | 666 | # 印出估計觀看人數 667 | visitors 668 | 669 | # 美國觀看人數 670 | us_visitors <- visitors[ ,1] 671 | 672 | # 美國平均觀看人數 673 | mean(us_visitors) 674 | ``` 675 | 676 | *** =sct 677 | ```{r} 678 | msg <- "不需要更改工作區已建立好的 `all_wars_matrix`。" 679 | test_object("all_wars_matrix", undefined_msg = msg, incorrect_msg = msg) 680 | test_object("ticket_prices_matrix", undefined_msg = msg, incorrect_msg = msg) 681 | 682 | test_object("visitors", 683 | incorrect_msg = "確認是否正確建立矩陣 `visitors`? 將 `all_wars_matrix` 除以 `ticket_prices_matrix` 就可以算出。") 684 | 685 | test_output_contains("visitors", incorrect_msg = "記得要將 `visitors` 印出來。") 686 | 687 | test_object("us_visitors", incorrect_msg = "你可以使用 `[,1]` 來選出 `visitors` 的第一欄並指派給 `us_visitors`!") 688 | test_output_contains("mean(us_visitors)", incorrect_msg = "一旦你建立好 `us_visitors` 就可以使用 `mean()` 來計算美國平均觀看人數並記得要把結果印出來。") 689 | 690 | success_msg("R 的原力與你同在,這是矩陣單元的最後一個練習,下一個章節是因素向量!") 691 | ``` 692 | 693 | 694 | -------------------------------------------------------------------------------- /chapter2.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title_meta : 第二章 3 | title : 向量 4 | description : "在第二章的課程中,我們要去拉斯維加斯一趟學習如何在 R 使用向量分析博弈的結果!完成本章節後,我們不僅會變成技巧高超的賭客,還將學會如何宣告向量、命名向量、從向量選取元素以及比較不同的向量。" 5 | 6 | --- type:NormalExercise xp:100 skills:1 key:44ae1c0203a5a327a8b7670514bc5c5d07f05a5c 7 | ## 宣告向量 8 | 9 | 覺得自己是個幸運的人嗎?讓本章節帶你到傳說中的統計學家天堂、罪惡都市 ─ **拉斯維加斯**! 10 | 你將利用 R 與資料分析的技巧來提升賭桌上的表現,並展開一場職業賭徒的冒險。本章節教你如何輕鬆記錄下注過程、如何針對這些記錄作簡單的分析,拉斯維加斯我們來囉! 11 | 12 | *** =instructions 13 | - 還記得在第一章學的嗎?宣告一個變數 `vegas` 並且將字串 `"Go!"` 指派給它,要注意大小寫在 R 是有差別的喔! 14 | 15 | *** =hint 16 | 在編輯區輸入以下的程式: 17 | ``` 18 | vegas <- "Go!" 19 | ``` 20 | 21 | *** =pre_exercise_code 22 | ```{r} 23 | # no pec 24 | ``` 25 | 26 | *** =sample_code 27 | ```{r} 28 | # 宣告變數 vegas 29 | vegas <- 30 | ``` 31 | 32 | *** =solution 33 | ```{r} 34 | # 宣告變數 vegas 35 | vegas <- "Go!" 36 | ``` 37 | 38 | *** =sct 39 | ```{r} 40 | test_object("vegas", incorrect_msg = "確認你是否有指派正確的值給變數 `vegas` ,要注意大小寫在R是有差別的喔!") 41 | success_msg("太棒了!前進下一個練習!") 42 | ``` 43 | 44 | 45 | --- type:NormalExercise xp:100 skills:1 key:bbc502a52a960a4d3d17fc01945551cb822cdffa 46 | ## 宣告向量(2) 47 | 48 | 保持專注! 49 | 50 | 致富的道路上,你會大量使用向量。向量是單一維度的陣列,可以包含數值、文字或者邏輯值。換句話說,向量是一種用來儲存資料的方法,例如每天在賭場中贏得或損失的金額,我們可用向量把它們紀錄儲存起來。 51 | 52 | R 使用[`c()`](http://www.rdocumentation.org/packages/base/functions/c)來創造向量,並使用逗號分隔向量中的元素,像是: 53 | 54 | ``` 55 | numeric_vector <- c(1, 2, 3) 56 | character_vector <- c("a", "b", "c") 57 | ``` 58 | 59 | 一旦你成功宣告了這些向量,就可以開始進行向量的計算。 60 | 61 | *** =instructions 62 | 宣告一個向量 `boolean_vector` 依序包含 3 個元素:`TRUE` 、 `FALSE` 與 `TRUE`,注意邏輯值不需要加引號。 63 | 64 | *** =hint 65 | 利用 `<-` 指派 `c(TRUE, FALSE, TRUE)` 給變數 `boolean_vector`。 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 | # 宣告 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 | # 宣告 boolean_vector 87 | boolean_vector <- c(TRUE, FALSE, TRUE) 88 | ``` 89 | 90 | *** =sct 91 | ```{r} 92 | msg <- "不需要更改宣告 `numeric_vector` 與 `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 = "確認你指派了正確的值給 `boolean_vector`,正確的值為 `c(TRUE, FALSE, TRUE)`,記得不要幫 `TRUE` 或 `FALSE` 加上引號,同時確認順序與說明一樣。") 97 | success_msg("完美!注意我們在 `c()` 中的逗號後面加上空白是為了增加程式的可讀性,我們會在下個練習中練習更多向量的宣告。") 98 | ``` 99 | 100 | 101 | --- type:NormalExercise xp:100 skills:1 key:25b255d971d82b1adb868a9bd8a1b583b6c071de 102 | ## 宣告向量(3) 103 | 104 | 經過一週的賭桌奮戰,你還沒有為自己贏到一台法拉利跑車,於是你打算運用資料分析超能力來分析過去這週的輸贏記錄: 105 | 106 | 撲克牌 `poker_vector` 部分: 107 | 108 | - 星期一贏 $140 109 | - 星期二輸 $50 110 | - 星期三贏 $20 111 | - 星期四輸 $120 112 | - 星期五贏 $240 113 | 114 | 俄羅斯輪盤 `roulette_vector` 部分: 115 | 116 | - 星期一輸 $24 117 | - 星期二輸 $50 118 | - 星期三贏 $100 119 | - 星期四輸 $350 120 | - 星期五贏 $10 121 | 122 | 過去一週你只玩了撲克牌與俄羅斯輪盤,你決定宣告兩個向量 `poker_vector` 與 `roulette_vector`。 123 | 124 | *** =instructions 125 | 將俄羅斯輪盤的**輸贏**金額指派給變數 `roulette_vector`。 126 | 127 | *** =hint 128 | 編輯區已經有了 `poker_vector` 的宣告範例,依樣畫葫蘆你可以順利宣告 `roulette_vector` 並注意輸錢是以負值記錄。 129 | 130 | *** =sample_code 131 | ```{r} 132 | # 星期一至五的撲克牌贏錢金額 133 | poker_vector <- c(140, -50, 20, -120, 240) 134 | 135 | # 星期一至五的俄羅斯輪盤贏錢金額 136 | roulette_vector <- 137 | ``` 138 | 139 | *** =solution 140 | ```{r} 141 | # 星期一至五的撲克牌贏錢金額 142 | poker_vector <- c(140, -50, 20, -120, 240) 143 | 144 | # 星期一至五的俄羅斯輪盤贏錢金額 145 | roulette_vector <- c(-24, -50, 100, -350, 10) 146 | ``` 147 | 148 | *** =sct 149 | ```{r} 150 | test_object("poker_vector", 151 | incorrect_msg = "確認是否指派正確的值給 `poker_vector`。") 152 | test_object("roulette_vector", 153 | incorrect_msg = "確認是否指派正確的值給 `roulette_vector` 並注意星期一至五的順序!") 154 | success_msg("太好了!記得你隨時可以在 R Console 輸入變數名稱後按輸入鍵( 155 | Enter) 156 | 檢查你宣告的向量,讓我們前進下一個練習!") 157 | ``` 158 | 159 | 160 | --- type:NormalExercise xp:100 skills:1 key:bfaa5f15a513859fff24771c6d0cd87082211092 161 | ## 為向量命名 162 | 163 | 資料分析師需要對資料細節有清楚的認知!在前一個練習中,我們已經宣告過去一週輸贏的記錄,如果能在向量中顯示每個金額對應的星期,資料看起來會更加一目瞭然。 164 | 165 | 我們可以使用 `names()` 函數來辦到這件事: 166 | 167 | ``` 168 | some_vector <- c("John Doe", "poker player") 169 | names(some_vector) <- c("Name", "Profession") 170 | ``` 171 | 172 | 這段程式首先宣告一個含有兩個元素的向量 `some_vector`,然後接著為這兩個元素命名,第一個元素名稱為姓名 `Name` ,第二個元素名稱為職業 `Profession`。 173 | 174 | 在 R Console 中印出 `some_vector`: 175 | 176 | ``` 177 | Name Profession 178 | "John Doe" "poker player" 179 | ``` 180 | 181 | *** =instructions 182 | - 編輯區有已完成的 `poker_vector` 贏錢記錄命名,接著請你用同樣方式對 `roulette_vector` 命名。 183 | 184 | *** =hint 185 | 使用 `names(roulette_vector)` 為 `roulette_vector` 命名,確認使用相同的向量名稱,記得英文字母的大小寫在 R 中是有差別的! 186 | 187 | *** =sample_code 188 | ```{r} 189 | # 星期一至五的撲克牌贏錢金額 190 | poker_vector <- c(140, -50, 20, -120, 240) 191 | 192 | # 星期一至五的俄羅斯輪盤贏錢金額 193 | roulette_vector <- c(-24, -50, 100, -350, 10) 194 | 195 | # 用星期一至五命名 poker_vector 196 | names(poker_vector) <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 197 | 198 | # 用星期一至五命名 roulette_vector 199 | ``` 200 | 201 | *** =solution 202 | ```{r} 203 | # 星期一至五的撲克牌贏錢金額 204 | poker_vector <- c(140, -50, 20, -120, 240) 205 | 206 | # 星期一至五的俄羅斯輪盤贏錢金額 207 | roulette_vector <- c(-24, -50, 100, -350, 10) 208 | 209 | # 用星期一至五命名 poker_vector 210 | names(poker_vector) <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 211 | 212 | # 用星期一至五命名 roulette_vector 213 | names(roulette_vector) <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 214 | ``` 215 | 216 | *** =sct 217 | ```{r} 218 | test_object("poker_vector", 219 | incorrect_msg = "不需要更改 `poker_vector`。") 220 | test_object("roulette_vector", 221 | incorrect_msg = "不需要更改 `roulette_vector`。") 222 | test_object("poker_vector", 223 | eq_condition = "equal", 224 | incorrect_msg = "不需要更改為 `poker_vector` 命名的程式,把注意力集中在 `roulette_vector`!") 225 | test_object("roulette_vector", 226 | eq_condition = "equal", 227 | incorrect_msg = "確認你有為 `roulette_vector` 正確地命名。使用上一行程式為 `poker_vector` 命名的同一個向量即可。") 228 | success_msg("作得好,前進下一個練習!") 229 | ``` 230 | 231 | 232 | --- type:NormalExercise xp:100 skills:1 key:cfa4561b5f565645ab272a96838ae690d6ecf621 233 | ## 為向量命名(2) 234 | 235 | 懶惰的人可以成為一個優秀的統計學家(假如你真的非常懶惰,你有很高的機率是個天生統計學天才。) 236 | 237 | 上一個練習中,你可能厭倦了不斷輸入週間日,這裡提供一個更有效率的方法,就是將週間日指派成一個**變數**! 238 | 239 | 如同你記錄撲克牌與俄羅斯輪盤贏錢金額的方式,你也可以宣告一個變數包含週間日的資訊,這樣就可以重複使用它。 240 | 241 | *** =instructions 242 | - 包含週間日的變數 `days_vector` 已經宣告好了。 243 | - 使用 `days_vector` 為 `poker_vector` 與 `roulette_vector`命名。 244 | 245 | *** =hint 246 | 如同使用 `names(poker_vector) <- days_vector` 來為 `poker_vector` 的元素命名一樣,對 `roulette_vector` 做一樣的事情。 247 | 248 | *** =pre_exercise_code 249 | ```{r} 250 | # no pec 251 | ``` 252 | 253 | *** =sample_code 254 | ```{r} 255 | # 星期一至五的撲克牌贏錢金額 256 | poker_vector <- c(140, -50, 20, -120, 240) 257 | 258 | # 星期一至五的俄羅斯輪盤贏錢金額 259 | roulette_vector <- c(-24, -50, 100, -350, 10) 260 | 261 | # 變數 days_vector 262 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 263 | 264 | # 指派變數 days_vector 給 roulette_vector 與 poker_vector 265 | names(poker_vector) <- 266 | names(roulette_vector) <- 267 | ``` 268 | 269 | *** =solution 270 | ```{r} 271 | # 星期一至五的撲克牌贏錢金額 272 | poker_vector <- c(140, -50, 20, -120, 240) 273 | 274 | # 星期一至五的俄羅斯輪盤贏錢金額 275 | roulette_vector <- c(-24, -50, 100, -350, 10) 276 | 277 | # 變數 days_vector 278 | days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") 279 | 280 | # 指派變數 days_vector 給 roulette_vector 與 poker_vector 281 | names(poker_vector) <- days_vector 282 | names(roulette_vector) <- days_vector 283 | ``` 284 | 285 | *** =sct 286 | ```{r} 287 | msg <- "不需要更改 `poker_vector` 、 `roulette_vector` 或 `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 = "確認是否指派 `days_vector` 作為 `poker_vector` 的命名。") 295 | test_object("roulette_vector", 296 | eq_condition = "equal", 297 | incorrect_msg = "確認是否指派 `days_vector` 作為 `roulette_vector`的命名。") 298 | success_msg("作得好!良心建議:永遠試著避免寫重複的程式。前進下一個練習並學習向量的數學運算!") 299 | ``` 300 | 301 | 302 | --- type:NormalExercise xp:100 skills:1 key:a0e5bb0a2dfc13b73a6edf7408aedaf100f156ef 303 | ## 計算加總贏錢金額 304 | 305 | 現在你有了命名過的撲克牌與俄羅斯輪盤的贏錢記錄,你可以開始施展點資料分析魔法。 306 | 307 | 你可能會想到以下這幾個問題: 308 | 309 | - 每日的總獲利或總損失為何? 310 | - 這週總計有沒有賠錢? 311 | - 在撲克牌與俄羅斯輪盤的各自表現如何? 312 | 313 | 要回答這些問題,你必須作一些向量的數學運算。 314 | 315 | 在 R 中,2 個向量相加為向量中各相同位置的元素相加,例如: 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 | 也可以用變數來代表向量: 324 | 325 | ``` 326 | a <- c(1, 2, 3) 327 | b <- c(4, 5, 6) 328 | c <- a + b 329 | ``` 330 | 331 | *** =instructions 332 | - 將 `A_vector` 與 `B_vector` 相加並指派給 `total_vector`。 333 | - 將 `total_vector` 印出來檢視結果。 334 | 335 | *** =hint 336 | 使用 `+` 將 `A_vector` 與 `B_vector` 相加,並利用 `<-` 將結果指派給 `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 | # 將 A_vector與 B_vector相加 349 | total_vector <- 350 | 351 | # 印出 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 | # 將 A_vector 與 B_vector 相加 361 | total_vector <- A_vector + B_vector 362 | 363 | # 印出 total_vector 364 | total_vector 365 | ``` 366 | 367 | *** =sct 368 | ```{r} 369 | msg <- "不需要更改 `A_vector` 或 `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 = "確認 `total_vector` 是否為 `A_vector` 加 `B_vector`。") 373 | test_output_contains("total_vector", incorrect_msg = "別忘了印出 `total_vector`! 只要加一行 `total_vector` 即可。") 374 | success_msg("作得好,前進下一個練習!") 375 | ``` 376 | 377 | 378 | --- type:NormalExercise xp:100 skills:1 key:647ae33cb77824ceb0b881a42da73a51dca46c95 379 | ## 計算加總贏錢金額(2) 380 | 381 | 現在瞭解 R 如何做向量的數學運算,該是把法拉利買回來的時候了!首先你需要了解這一週每日的總獲利,每日的總獲利就是將每日在撲克牌與俄羅斯輪盤的輸贏錢金額加總。 382 | 383 | 其實說明白些就是把 `roulette_vector` 與 `poker_vector` 相加。 384 | 385 | *** =instructions 386 | 將變數 `total_daily` 宣告為每日的總獲利或總損失(撲克牌與俄羅斯輪盤)。 387 | 388 | *** =hint 389 | 跟前一個練習類似,將 2 個向量相加並指派給新變數 `total_daily`。 390 | 391 | *** =pre_exercise_code 392 | ```{r} 393 | # no pec 394 | ``` 395 | 396 | *** =sample_code 397 | ```{r} 398 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告 total_daily 為每日的總獲利或總損失 406 | total_daily <- 407 | ``` 408 | 409 | *** =solution 410 | ```{r} 411 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告 total_daily 為每日的總獲利或總損失 419 | total_daily <- poker_vector + roulette_vector 420 | ``` 421 | 422 | *** =sct 423 | ```{r} 424 | msg = "不需要更改 `poker_vector` 與 `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 = "確認你將 `poker_vector` 與 `roulette_vector` 相加後指派給 `total_daily`。") 430 | 431 | success_msg("太棒了,前進下一個練習!") 432 | ``` 433 | 434 | 435 | --- type:NormalExercise xp:100 skills:1 key:ab4e6dfbddc58056dbc98092c89bf568302eecae 436 | ## 計算加總贏錢金額 (3) 437 | 438 | 從前一個練習看起來上週好像是輸贏參半,你擔心對加總結算後的結果會感到失望。 439 | 440 | 能夠回答這個問題的函數是[`sum()`](http://www.rdocumentation.org/packages/base/functions/sum)。它可以加總向量中所有的元素,例如計算在撲克牌的總獲利或總損失: 441 | 442 | ``` 443 | total_poker <- sum(poker_vector) 444 | ``` 445 | 446 | *** =instructions 447 | - 計算在俄羅斯輪盤的總獲利或總損失並將結果指派給 `total_roulette`。 448 | - 有了撲克牌與俄羅斯輪盤的總獲利或總損失後,就可以簡單計算 `total_week` (即這一週的總獲利或總損失)。 449 | - 印出 `total_week`。 450 | 451 | *** =hint 452 | 使用[`sum()`](http://www.rdocumentation.org/packages/base/functions/sum)函數得到 `roulette_vector` 的總合, `total_week` 就是 `roulette_vector` 加 `poker_vector`。 453 | 454 | *** =pre_exercise_code 455 | ```{r} 456 | # no pec 457 | ``` 458 | 459 | *** =sample_code 460 | ```{r} 461 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 撲克牌的總贏錢金額 469 | total_poker <- sum(poker_vector) 470 | 471 | # 俄羅斯輪盤的總贏錢金額 472 | total_roulette <- 473 | 474 | # 總贏錢金額 475 | total_week <- 476 | 477 | # 印出 total_week 478 | 479 | ``` 480 | 481 | *** =solution 482 | ```{r} 483 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 撲克牌的總贏錢金額 491 | total_poker <- sum(poker_vector) 492 | 493 | # 俄羅斯輪盤的總贏錢金額 494 | total_roulette <- sum(roulette_vector) 495 | 496 | # 總贏錢金額 497 | total_week <- total_roulette + total_poker 498 | 499 | # 印出 total_week 500 | total_week 501 | ``` 502 | 503 | *** =sct 504 | ```{r} 505 | msg = "不需要更改 `poker_vector` and `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 = "確認是否有將 `poker_vector` 的總和指派給 `total_poker`。") 511 | test_object("total_roulette", 512 | incorrect_msg = "確認是否有將 `total_roulette` 的總和指派給 `roulette_vector`。") 513 | test_object("total_week", 514 | incorrect_msg = "確認是否有將 `total_roulette` 加 `total_poker` 的結果指派給 `total_week`。") 515 | 516 | test_output_contains("total_week", incorrect_msg = "別忘了再寫一行 `total_week` 把結果印出來。") 517 | success_msg("作得好,但這個結果真是令人難過...") 518 | ``` 519 | 520 | 521 | --- type:NormalExercise xp:100 skills:1 key:d4aec72e46e130bfc7e3992f07bd6d6cc3b8179b 522 | ## 比較總贏錢金額 523 | 524 | 看起來這一週的豪賭讓你賠了錢,是時候深度分析該如何調整策略了...。 525 | 526 | 經過一番思考,你認為問題是出在自己玩俄羅斯輪盤的技巧比玩撲克牌來得差,也許在撲克牌的總贏錢金額比( `>` )俄羅斯輪盤來得高。 527 | 528 | *** =instructions 529 | - 如同前一個練習,使用 `sum()` 函數來分別計算 `total_poker` 與 `total_roulette`。 530 | - 使用 `>` 來比較你在撲克牌的總贏錢金額是否比俄羅斯輪盤還要高,並把比較結果印出來。你會如何判讀這個結果,你應該要花更多精力在撲克牌或俄羅斯輪盤呢? 531 | 532 | *** =hint 533 | - 其實在前一個練習你已經算好一部份了! 534 | - 只要輸入 `6 > 5` 就可以檢查 6 是否比 5 大,這會回傳一個邏輯值(`TRUE` 或 `FALSE`)。 535 | 536 | *** =pre_exercise_code 537 | ```{r} 538 | # no pec 539 | ``` 540 | 541 | *** =sample_code 542 | ```{r} 543 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 計算撲克牌與俄羅斯輪盤的總贏錢金額 551 | total_poker <- 552 | total_roulette <- 553 | 554 | # 判斷撲克牌的總贏錢金額是否比俄羅斯輪盤為高 555 | 556 | ``` 557 | 558 | *** =solution 559 | ```{r} 560 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 計算撲克牌與俄羅斯輪盤的總贏錢金額 568 | total_poker <- sum(poker_vector) 569 | total_roulette <- sum(roulette_vector) 570 | 571 | # 判斷撲克牌的總贏錢金額是否比俄羅斯輪盤為高 572 | total_poker > total_roulette 573 | ``` 574 | 575 | *** =sct 576 | ```{r} 577 | msg <- "不需要更改 `poker_vector` 與 `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 = "確認是否將 `poker_vector` 的總和(使用 `sum()` )指派給 `total_poker`。") 584 | test_object("total_roulette", 585 | incorrect_msg = "確認是否將 `roulette_vector` 的總和(使用 `sum()` )指派給 `total_roulette`。") 586 | test_output_contains("total_poker > total_roulette", 587 | incorrect_msg = "確認是否成功比較 `total_poker` 與 `total_roulette` ,使用 `total_poker > total_roulette` 來作比較。") 588 | success_msg("作得好,前進下一個練習!") 589 | ``` 590 | 591 | 592 | --- type:NormalExercise xp:100 skills:1 key:cf3480826ff4ed5aa06b4fccf8fa19b30e2f02f6 593 | ## 選擇向量中的元素:美好時光 594 | 595 | 你的猜測是對的,過去一週在賭桌上的奮鬥顯示你的撲克牌技巧似乎比俄羅斯輪盤好。 596 | 597 | 另外一個可能是你在上一週前幾天的表現比後幾天要好,看來你最後幾天喝了太多瑪格麗特酒(Margarita)囉...。 598 | 599 | 要回答這個問題,你只需要檢視部分 `total_vector` ,換句話說,就是在向量中選擇特定的元素。在R利用中括號就可以選擇向量(之後是矩陣、資料框...)中的元素。例如,要選擇第一個元素就輸入 `poker_vector[1]` ,要選擇第二個元素就輸入 `poker_vector[2]` ...等。注意第一個元素的索引值是 1,不像其他程式語言第一個元素的索引值是 0。 600 | 601 | *** =instructions 602 | 將星期三的撲克牌贏錢金額指定給變數 `poker_wednesday`。 603 | 604 | *** =hint 605 | 星期三是 `poker_vector` 中的第三個元素,可以使用 `poker_vector[3]` 來選擇。 606 | 607 | *** =pre_exercise_code 608 | ```{r} 609 | # no pec 610 | ``` 611 | 612 | *** =sample_code 613 | ```{r} 614 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告一個選擇撲克牌星期三贏錢金額的變數 622 | poker_wednesday <- 623 | ``` 624 | 625 | *** =solution 626 | ```{r} 627 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告一個選擇撲克牌星期三贏錢金額的變數 635 | poker_wednesday <- poker_vector[3] 636 | ``` 637 | 638 | *** =sct 639 | ```{r} 640 | msg = "不需要更改 `poker_vector` 與 `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 = "請確認是否有宣告變數 `poker_wednesday`。", 646 | incorrect_msg = "看起來 `poker_wednesday` 並沒有從 `poker_vector` 選到正確的數值。") 647 | success_msg("太棒了,R 還可以從向量中一次選擇多個元素,在下一個練習中就可以學會!") 648 | ``` 649 | 650 | 651 | --- type:NormalExercise xp:100 skills:1 key:961b3b1c8a4721c71a6f099daacf17156b59b6a1 652 | ## 選擇向量中的元素:美好時光(2) 653 | 654 | 何不分析一下中間幾天的表現呢? 655 | 656 | 在中括號中告知 R 你要從向量中選擇哪些元素,假如你想選擇星期一與星期五,在中括號中使用 `c(1, 5)` 即可,參考這個範例: 657 | 658 | ``` 659 | poker_vector[c(1, 5)] 660 | ``` 661 | 662 | *** =instructions 663 | 指派星期二、星期三與星期四的撲克牌贏錢金額給變數 `poker_midweek`。 664 | 665 | *** =hint 666 | 中括號裡使用向量 `c(2, 3, 4)` 來選擇 `poker_vector` 中的元素。 667 | 668 | *** =pre_exercise_code 669 | ```{r} 670 | # no pec 671 | ``` 672 | 673 | *** =sample_code 674 | ```{r} 675 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告一個選擇後的變數 683 | poker_midweek <- 684 | ``` 685 | 686 | *** =solution 687 | ```{r} 688 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告一個選擇後的變數 696 | poker_midweek <- poker_vector[c(2, 3, 4)] 697 | ``` 698 | 699 | *** =sct 700 | ```{r} 701 | msg = "不需要更改 `poker_vector` 與 `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 = "看起來 `poker_midweek` 並沒有從 `poker_vector` 選到正確的數值。你應該要在中括號中輸入 `c(2, 3, 4)`。") 707 | success_msg("作得好,前進下一個練習作更多的選擇!"); 708 | ``` 709 | 710 | 711 | --- type:NormalExercise xp:100 skills:1 key:30b0e8c9fe371d8f3f1391c1088fce05c195c52a 712 | ## 選擇向量中的元素:美好時光(3) 713 | 714 | 利用 `c(2, 3, 4)` 從 `poker_vector`中選擇元素不是非常方便,許多統計學家都是懶人,所以他們創造了一個更簡單的方法 `c(2, 3, 4)` 可以簡化為 `2:4`。 715 | 716 | 所以想找出中間幾天的贏錢金額的另外一個方法是用 `poker_vector[2:4]`。注意 `2:4` 要擺在中括號裡面才能選出第二至第四個元素。 717 | 718 | *** =instructions 719 | 將星期二到星期五的俄羅斯輪盤贏錢金額指派給 `roulette_selection_vector` ,使用 `:` 會很方便。 720 | 721 | *** =hint 722 | 在中括號裡放置 `2:5` 選擇 `roulette_vector` 中的第二至第五個元素指派給 `roulette_selection_vector` 。 723 | 724 | *** =sample_code 725 | ```{r} 726 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告一個選擇後的變數 734 | roulette_selection_vector <- 735 | ``` 736 | 737 | *** =solution 738 | ```{r} 739 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 宣告一個選擇後的變數 747 | roulette_selection_vector <- roulette_vector[2:5] 748 | ``` 749 | 750 | *** =sct 751 | 752 | ```{r} 753 | msg = "不需要更改 `poker_vector` 與 `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 = "請確認是否有宣告變數 `roulette_selection_vector`。", 759 | incorrect_msg = "看起來 `roulette_selection_vector` 並沒有從 `roulette_vector` 選到正確的數值,請確認索引值是否正確。") 760 | success_msg("太棒了!冒號非常有用且常見,把它牢記並前進下一個練習!") 761 | ``` 762 | 763 | 764 | --- type:NormalExercise xp:100 skills:1 key:479dfd0f8bc1f275c5cfd65b9f801be9f6498855 765 | ## 選擇向量中的元素:美好時光(4) 766 | 767 | 另外一個完成前一個練習的方式為指定元素的命名(Monday, Tuesday, ...)而不是用索引值,例如: 768 | 769 | ``` 770 | poker_vector["Monday"] 771 | ``` 772 | 773 | 能夠將 `poker_vector` 中的第一個元素選出,因為 `"Monday"` 是第一個元素的命名。 774 | 775 | 如同你在前一個練習所做的,用元素的命名同樣可以選出多個元素,例如: 776 | 777 | ``` 778 | poker_vector[c("Monday","Tuesday")] 779 | ``` 780 | 781 | *** =instructions 782 | - 用命名選擇 `poker_vector` 的前三個元素: `"Monday"` 、 `"Tuesday"` 與 `"Wednesday"`,將選擇的結果指定給 `poker_start`。 783 | - 利用[`mean()`](http://www.rdocumentation.org/packages/base/functions/mean)凾數計算 `poker_start` 的平均數並將結果印出來。 784 | 785 | *** =hint 786 | - 在中括號輸入 `c("Monday", "Tuesday", "Wednesday")` 選擇 `poker_vector` 裡面的元素。 787 | - 使用 `mean(poker_start)` 獲得 `poker_start` 裡面元素的平均值,你不需要所有撲克牌元素的平均贏錢金額,只要前三天就可以。 788 | 789 | *** =pre_exercise_code 790 | ```{r} 791 | # no pec 792 | ``` 793 | 794 | *** =sample_code 795 | ```{r} 796 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 選擇星期一至三的撲克牌贏錢金額 804 | poker_start <- 805 | 806 | # 計算 poker_start 元素的平均值 807 | 808 | ``` 809 | 810 | *** =solution 811 | ```{r} 812 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 選擇星期一至三的撲克牌贏錢金額 820 | poker_start <- poker_vector[c("Monday", "Tuesday", "Wednesday")] 821 | 822 | # 計算 poker_start 元素的平均值 823 | mean(poker_start) 824 | ``` 825 | 826 | *** =sct 827 | ```{r} 828 | msg = "不需要更改 `poker_vector` 與 `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 = "看起來 `poker_start` 並沒有選到 `poker_vector` 的前三個值,你可以將 `c(\"Monday\", \"Tuesday\", \"Wednesday\")` 放在中括號中。") 834 | test_output_contains("mean(poker_start)", incorrect_msg = "請確認你是否有計算出 `poker_start` 的平均值並且將結果印出來?記得使用 `mean(poker_start)`。") 835 | success_msg("太好了,除了用索引值或命名可以選擇以外,你會在下一個練習中學到如何用比較的方式選擇向量中的元素!"); 836 | ``` 837 | 838 | 839 | --- type:NormalExercise xp:100 skills:1 key:11850f807f9b0fad101a88004291b7ced6397083 840 | ## 用比較的方式選擇 - 第一步 841 | 842 | 使用比較運算子可以用更主動的方法解決前一個練習的問題。 843 | 844 | R使用的比較運算子有: 845 | 846 | - `<` 小於 847 | - `>` 大於 848 | - `<=` 小於或等於 849 | - `>=` 大於或等於 850 | - `==` 等於 851 | - `!=` 不等於 852 | 853 | 在 R Console 輸入 `6 > 5` 會回傳 `TRUE`。R 的好處是可以對向量使用比較運算子,例如: 854 | 855 | ``` 856 | > c(4, 5, 6) > 5 857 | [1] FALSE FALSE TRUE 858 | ``` 859 | 860 | 這段程式測試向量中的每個元素是否滿足比較運算子的條件,回傳 `TRUE` 或 `FALSE`。 861 | 862 | *** =instructions 863 | - 檢查 `poker_vector` 中哪些元素為正(即 > 0) 並指派這個結果給 `selection_vector`。 864 | - 印出 `selection_vector` 讓你知道每天是贏錢(`TRUE`)或者輸錢(`FALSE`)。 865 | 866 | *** =hint 867 | 為了檢驗哪些天你的撲克牌在贏錢,R 會利用 `some_vector > 0` 檢查 `poker_vector` 中的每個元素是否大於零。 868 | 869 | *** =pre_exercise_code 870 | ```{r} 871 | # no pec 872 | ``` 873 | 874 | *** =sample_code 875 | ```{r} 876 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 哪幾天你玩撲克牌是贏錢的 884 | selection_vector <- 885 | 886 | # 印出 selection_vector 887 | 888 | ``` 889 | 890 | *** =solution 891 | ```{r} 892 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 哪幾天你玩撲克牌是贏錢的 900 | selection_vector <- poker_vector > 0 901 | 902 | # 印出 selection_vector 903 | selection_vector 904 | ``` 905 | 906 | *** =sct 907 | ```{r} 908 | msg <- "不需要更改 `poker_vector` 與 `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 = "看起來 `selection_vector` 沒有包含正確的元素,記得R的向量運算是以元素對元素的方式在進行。") 914 | test_output_contains("selection_vector", incorrect_msg = "別忘了加入一行 `selection_vector` 把結果印出") 915 | success_msg("太棒了!") 916 | ``` 917 | 918 | 919 | --- type:NormalExercise xp:100 skills:1 key:8521f1e1993a6154e68ccfa75e29e517955343ac 920 | ## 用比較的方式選擇 - 第二步 921 | 922 | 善用比較會讓你的分析省時省力,與其自己檢查要選擇哪幾天,不如讓 R 告訴你哪些天的撲克牌贏錢金額是正的。 923 | 924 | 在前一個練習中,使用 `selection_vector <- poker_vector > 0` 可找出哪幾天撲克牌贏錢金額為正的日子,除此之外,你現在還想知道這幾天分別贏了多少錢。 925 | 926 | 你可以把 `selection_vector` 放在中括號裡並接在 `poker_vector` 之後: 927 | 928 | ``` 929 | poker_vector[selection_vector] 930 | ``` 931 | 932 | R 就會把 `selection_vector` 之中符合 `TRUE` 的元素選擇出來。 933 | 934 | *** =instructions 935 | 在中括號裡使用 `selection_vector` 來將撲克牌贏錢的那幾天指派給 `poker_winning_days`。 936 | 937 | *** =hint 938 | 利用 `poker_vector[selection_vector]` 從 `poker_vector` 中選擇適當的元素並指派給 `poker_winning_days`。 939 | 940 | *** =pre_exercise_code 941 | ```{r} 942 | # no pec 943 | ``` 944 | 945 | *** =sample_code 946 | ```{r} 947 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 哪幾天你玩撲克牌是贏錢的 955 | selection_vector <- poker_vector > 0 956 | 957 | # 從 poker_vector 中選出這些天 958 | poker_winning_days <- 959 | ``` 960 | 961 | *** =solution 962 | ```{r} 963 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 哪幾天你玩撲克牌是贏錢的 971 | selection_vector <- poker_vector > 0 972 | 973 | # 從 poker_vector 中選出這些天 974 | poker_winning_days <- poker_vector[selection_vector] 975 | ``` 976 | 977 | *** =sct 978 | ```{r} 979 | msg = "不需要更改 `poker_vector` 與 `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 = "不需要更改 `selection_vector` 的計算方式。") 984 | test_object("poker_winning_days", 985 | incorrect_msg = "看起來 `poker_winning_days` 沒有包含正確的結果,請輸入 `poker_vector[selection_vector]`。") 986 | success_msg("作得好,前進下一個練習!") 987 | ``` 988 | 989 | 990 | --- type:NormalExercise xp:100 skills:1 key:921c6ad3b79b9b3532c7f4201d5202516b755324 991 | ## 進階選擇 992 | 993 | 就如前面的練習,你也想知道有哪幾天俄羅斯輪盤是有贏錢的。 994 | 995 | *** =instructions 996 | - 宣告變數 `selection_vector` ,這次要檢驗在哪些天俄羅斯輪盤有贏錢。 997 | - 從 `roulette_vector` 中選出金額為正的天數指派給 `roulette_winning_days`。 998 | 999 | *** =hint 1000 | 宣告 `selection_vector` 之後使用 `roulette_vector[selection_vector]` 將 `roulette_vector` 中的正數選出。 1001 | 1002 | *** =pre_exercise_code 1003 | ```{r} 1004 | # no pec 1005 | ``` 1006 | 1007 | *** =sample_code 1008 | ```{r} 1009 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 哪幾天你玩俄羅斯輪盤是贏錢的 1017 | selection_vector <- 1018 | 1019 | # 從 roulette_vector 中選出這些天 1020 | roulette_winning_days <- 1021 | ``` 1022 | 1023 | *** =solution 1024 | ```{r} 1025 | # 星期一至五的撲克牌與俄羅斯輪盤贏錢金額 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 | # 哪幾天你玩俄羅斯輪盤是贏錢的 1033 | selection_vector <- roulette_vector > 0 1034 | 1035 | # 從 roulette_vector 中選出這些天 1036 | roulette_winning_days <- roulette_vector[selection_vector] 1037 | ``` 1038 | 1039 | *** =sct 1040 | ```{r} 1041 | msg = "不需要更改 `poker_vector` 與 `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 = "看起來 `selection_vector` 沒有包含正確的結果,使用 `roulette_vector > 0`。") 1047 | test_object("roulette_winning_days", 1048 | incorrect_msg = "看起來 `roulette_winning_days` 沒有包含正確的結果,使用 `roulette_vector[selection_vector]`。") 1049 | 1050 | success_msg("太棒了,你完成了本章節的最後一個練習,接下來會介紹二維的向量:矩陣。") 1051 | ``` 1052 | 1053 | 1054 | 1055 | --------------------------------------------------------------------------------