# Clear Workspace
rm(list = ls())
# Load libraries
library(dplyr)
library(readr)
library(stringr)
library(tidyr)
library(ggplot2)
# Working directory path
data_path <- "D:\\DATA_SCIENCE\\R_COURSE_CASED\\Lecture_3\\multiple_choice_responses_aDung.csv"
# Load data
df_raw <- read_csv(data_path, skip = 1)Tại sao trong đoạn mã đọc dữ liệu ở trên lại sử dụng skip = 1 để loại bỏ dòng 1 khi đọc vào dữ liệu?
Answer: Dòng 1 chứa số thứ tự câu hỏi. Có thể sử dụng dòng này để làm tên biến (tương ứng với từng cột dữ liệu) nhưng việc đặt tên như vậy không giúp ích cho việc phân tích dữ liệu vì cách đánh số không chứa thông tin gì về cột dữ liệu. Trên thực tế ta sử dụng nội dung câu hỏi (chứa ở dòng số 2) làm tên cột biến.
Tên các cột biến có sử dụng dấu cách (space). Hãy thay thế tất cả các dấu cách bằng dấu gạch dưới (underscore).
Tách ra data frame chỉ gồm hai cột biến là What_is_your_gender?_-_Selected_Choice và In_which_country_do_you_currently_reside? rồi đổi tên cho chúng lần lượt thành gender và nation
Tính toán tỉ lệ nữ làm nghề Data Science cho tất cả các quốc gia trong mẫu khảo sát
# Tinh so luong respondents cho tung quoc gia, luu thanh df_country
df_country_gender %>% group_by(nation, gender) %>% count() -> df_country
# Chuyen df_country sang wide form
df_country %>% pivot_wider(names_from = gender, values_from = n) -> df_country_wide
# Tinh ti le nu cho tung quoc gia, lam tron 2 chu so sau dau phay va sap xep giam dan.
# Ghi chu: Bo qua cac quan sat khong ro gioi tinh (Prefer Not to say/Prefer to self-describe)
df_country_wide %>%
mutate(female_rate = Female/(Female + Male)) %>%
arrange(-female_rate) -> df_country_wide
df_country_wide## # A tibble: 59 x 6
## # Groups: nation [59]
## nation Female Male `Prefer not to s~ `Prefer to self-de~ female_rate
## <chr> <int> <int> <int> <int> <dbl>
## 1 Tunisia 33 35 NA NA 0.485
## 2 Philippines 19 41 5 NA 0.317
## 3 Iran, Islamic~ 28 67 1 NA 0.295
## 4 Malaysia 22 53 5 NA 0.293
## 5 Kenya 29 85 NA NA 0.254
## 6 Ireland 22 65 2 NA 0.253
## 7 Turkey 66 218 3 1 0.232
## 8 Indonesia 38 127 1 1 0.230
## 9 Canada 99 334 13 4 0.229
## 10 Thailand 15 51 1 NA 0.227
## # ... with 49 more rows
Lấy ra danh sách 20 quốc gia bao gồm Việt Nam và 19 quốc gia có tỉ lệ nữ làm Data Science lớn nhất (top 19)
Sử dụng dữ liệu có được ở Q5 hãy tạo ra (hoặc mô phỏng) lại biểu đồ Bar ở nhằm biểu diễn tỉ lệ Nữ làm Data Science cho 20 quốc gia đã được chọn như sau
# Doi ten cho mot so quoc gia vi qua dai
# Sap xep theo chieu ti le nu giam dan
df_country_20 %>%
mutate(nation = case_when(str_detect(nation, "United Kingdom") ~ "United Kingdom",
str_detect(nation, "Iran") ~ "Iran",
str_detect(nation, "America") ~ "USA",
TRUE ~ nation)) %>%
#mutate(male_rate = 1 - female_rate) %>%
arrange(female_rate) -> df_sorted
# ????
df_sorted %>% mutate(nation = factor(nation, levels = df_sorted$nation)) -> df_sorted
# Chuan bi du lieu cho ve bieu do
# Tao label cho female_rate
df_sorted %>%
select("nation", "Female", "Male", "female_rate") %>%
pivot_longer(cols = c("Female", "Male"), names_to = "gender") %>%
mutate(label = as.character(round(female_rate,3)*100)) %>%
mutate(label = case_when(str_detect(label,"\\.") ~ str_c(label,"%"),
TRUE ~ str_c(label,".0%"))) -> df_long
# Ve bieu do
library(viridis)
df_long %>%
ggplot(aes(x = value, y = nation, fill = gender)) +
geom_col(position = "fill") +
theme_minimal() +
theme(legend.position = "top", legend.title = element_blank()) +
theme(axis.title = element_blank()) +
theme(axis.ticks.y = element_blank()) +
theme(panel.grid = element_blank()) +
scale_x_continuous(labels = paste0(seq(0, 100, 25), "%"), expand = c(0, 0)) +
geom_text(aes(x = 1, y = nation, label = label), color = "white", hjust = 1.2, size = 3) +
labs(title = "Fact 1: Women in Machine Learning and Data Science Community",
x = NULL, y = NULL,
caption = "Source: 2019 Kaggle ML & DS Survey")# Clear Workspace
rm(list = ls())
# Load libraries
library(dplyr)
library(readr)
library(stringr)
library(tidyr)
library(ggplot2)
# Working directory path
data_path <- "D:\\DATA_SCIENCE\\R_COURSE_CASED\\Lecture_3\\multiple_choice_responses_aDung.csv"
# Load data
df_raw <- read_csv(data_path, skip = 1)
# Doi ten
df_raw %>% names() %>% str_replace_all(" ","_") -> new_names
names(df_raw) <- new_names
df_raw %>%
select(`What_is_your_gender?_-_Selected_Choice`,
`In_which_country_do_you_currently_reside?`) -> df_mini
names(df_mini) <- c("gender", "country")
some_genders <- c("Male", "Female")
df_mini %>%
filter(gender %in% some_genders) -> df_mini
library(tidyr)
df_mini %>%
group_by(gender, country) %>%
count() %>%
pivot_wider(names_from = "gender", values_from = "n") %>%
mutate(rate = Female/(Female + Male)) -> df_rate
# Loc top 19 va Viet Nam
# Cach 1
df_rate %>%
ungroup() %>%
top_n(n = 19, wt = rate) -> df_top19
# Cach 2
df_rate %>%
ungroup() %>%
arrange(-rate) %>%
slice(1:19) -> df_top19_2
# Vi sao can dung ungroup
# df_rate chiu anh huong boi group_by
str(df_rate)## tibble [59 x 4] (S3: grouped_df/tbl_df/tbl/data.frame)
## $ country: chr [1:59] "Algeria" "Argentina" "Australia" "Austria" ...
## $ Female : int [1:59] 12 13 44 5 7 12 5 79 99 10 ...
## $ Male : int [1:59] 46 108 218 47 127 55 62 643 334 81 ...
## $ rate : num [1:59] 0.2069 0.1074 0.1679 0.0962 0.0522 ...
## - attr(*, "groups")= tibble [59 x 2] (S3: tbl_df/tbl/data.frame)
## ..$ country: chr [1:59] "Algeria" "Argentina" "Australia" "Austria" ...
## ..$ .rows : list<int> [1:59]
## .. ..$ : int 1
## .. ..$ : int 2
## .. ..$ : int 3
## .. ..$ : int 4
## .. ..$ : int 5
## .. ..$ : int 6
## .. ..$ : int 7
## .. ..$ : int 8
## .. ..$ : int 9
## .. ..$ : int 10
## .. ..$ : int 11
## .. ..$ : int 12
## .. ..$ : int 13
## .. ..$ : int 14
## .. ..$ : int 15
## .. ..$ : int 16
## .. ..$ : int 17
## .. ..$ : int 18
## .. ..$ : int 19
## .. ..$ : int 20
## .. ..$ : int 21
## .. ..$ : int 22
## .. ..$ : int 23
## .. ..$ : int 24
## .. ..$ : int 25
## .. ..$ : int 26
## .. ..$ : int 27
## .. ..$ : int 28
## .. ..$ : int 29
## .. ..$ : int 30
## .. ..$ : int 31
## .. ..$ : int 32
## .. ..$ : int 33
## .. ..$ : int 34
## .. ..$ : int 35
## .. ..$ : int 36
## .. ..$ : int 37
## .. ..$ : int 38
## .. ..$ : int 39
## .. ..$ : int 40
## .. ..$ : int 41
## .. ..$ : int 42
## .. ..$ : int 43
## .. ..$ : int 44
## .. ..$ : int 45
## .. ..$ : int 46
## .. ..$ : int 47
## .. ..$ : int 48
## .. ..$ : int 49
## .. ..$ : int 50
## .. ..$ : int 51
## .. ..$ : int 52
## .. ..$ : int 53
## .. ..$ : int 54
## .. ..$ : int 55
## .. ..$ : int 56
## .. ..$ : int 57
## .. ..$ : int 58
## .. ..$ : int 59
## .. ..@ ptype: int(0)
## ..- attr(*, ".drop")= logi TRUE
## tibble [19,350 x 2] (S3: tbl_df/tbl/data.frame)
## $ gender : chr [1:19350] "Male" "Male" "Female" "Male" ...
## $ country: chr [1:19350] "France" "India" "Germany" "Australia" ...
bind_rows(df_top19_2, df_rate %>% ungroup() %>% filter(country == "Viet Nam")) -> df_total
df_total %>%
pivot_longer(cols = c("Female", "Male"), names_to = "gender", values_to = "value") -> df_plot
df_plot %>%
mutate(country = case_when(str_detect(country, "America") ~ "United States",
str_detect(country, "Kingdom") ~ "United Kingdom",
str_detect(country, "Iran") ~ "Iran",
TRUE ~ country)) -> df_plot
df_plot %>%
filter(duplicated(country)) %>%
arrange(rate) -> df_arranged
df_plot %>%
mutate(country = factor(country, levels = df_arranged$country)) %>%
#df_arranged$country[20:1] neu di cung arrange(-rate)
ggplot(aes(x = country, y = value, fill = gender)) +
geom_col(position = "fill") +
coord_flip() +
theme(axis.title = element_blank(),
axis.ticks = element_blank()) # Clear Workspace
rm(list = ls())
# Load required library
library(dplyr)
library(rvest)
library(stringr)
library(stringi)
library(ggplot2)Object có tên all_links_communes_level được tạo ra đoạn R Codes dưới đây:
all_links <- "https://www.citypopulation.de/Vietnam.html"
pg <- read_html(all_links)
m <- html_nodes(pg, "a")
k <- html_attr(m, "href")
all_links_communes_level <- str_c("https://www.citypopulation.de/en/vietnam/", k[-c(1:6)])Thuộc dạng dữ liệu gì? Mỗi phần tử của all_links_communes_level là link dẫn đến thông tin gì?
Dữ liệu kiểu character/text. Cụ thể là mỗi phần tử là text chứa đường link dẫn đến thông tin về hành chính của từng tỉnh/thành phố ở Việt Nam. Thông tin về mỗi tỉnh được thể hiện qua
Bản đồ hành chính của tỉnh + mật độ dân số của từng huyện khi trỏ chuột đến vị trí tương ứng trên bản đồ
Bảng số liệu về dân số của từng tỉnh
Ngoài ra còn rất nhiều thông tin khác khi click chuột vào các tab.
Xét đoạn mã dưới đây:
## [1] "https://www.citypopulation.de/en/vietnam/cantho/admin/"
specific_link %>%
read_html() %>%
html_nodes(xpath = '//*[@id="tl"]') %>%
html_table(fill = TRUE) %>%
.[[1]] -> df
head(df)## Name Status PopulationCensus2009-04-01
## 1 Bình Th<U+1EE7>y Urban District 113,565 <U+2192>
## 2 An Th<U+1EDB>i Ward 18,499 <U+2192>
## 3 Bình Th<U+1EE7>y Ward 18,307 <U+2192>
## 4 Bùi H<U+1EEF>u Nghia Ward 11,745 <U+2192>
## 5 Long Hòa Ward 16,450 <U+2192>
## 6 Long Tuy<U+1EC1>n Ward 15,232 <U+2192>
Trong đoạn mã trên nếu thay all_links_communes_level[1] thành all_links_communes_level[2] thì hệ quả sẽ là gì? Có thể thay thành all_links_communes_level[100] được không?
Số [1] chỉ định phần tử đầu tiên của vector all_link_communes_level, tương ứng với “cantho/admin/”. Lúc này specific_link chứa đường link dẫn đến trang thông tin của tỉnh Cần Thơ.
Khi thay thành số [2] thì specific_link được gán với đường link dẫn đến trang thông tin của tỉnh thứ 2 trong danh sách là Đà Nẵng.
Không thể thay thành …[100] vì all_links_communes_level chỉ có 63 phần tử, tương ứng với 63 tỉnh/thành phố. (Nếu để 100 thì specific_link sẽ báo giá trị NA).
Từ phân tích và nhận xét rút ra ở Q2 hãy viết một hàm mà nhận input là địa chỉ link của HTML và trả về kết quả (output) là một Data Frame chứa thông tin về dân số theo Huyện và Xã tương ứng với địa chỉ link của HTML.
Từ dữ liệu đã có ở Q3 hãy vẽ Choropleth Map minh họa mật độ dân số của Việt Nam theo cấp: (a) Tình, (b) Huyện. Giải thuyết rằng những số liệu về dân số thu được (kể cả cấp Huyện lẫn Xã) chính là mật độ dân số
Bước 1. Load dữ liệu dân số
# Su dung for loop thay vi ham lapply
m <- length(all_links_communes_level)
empty_df <- data.frame()
for (k in 1:m) {
my_df <- data_extract(all_links_communes_level[k])
empty_df <- bind_rows(empty_df, my_df)
}
# Su dung ham extract du lieu de lay ve du lieu cho cac tinh
lapply(all_links_communes_level, data_extract) -> all_provinces
# Noi cac bang du lieu cua tung tinh tao thanh bo du lieu ca quoc gia
do.call("bind_rows", all_provinces) -> vn_pop_data
# Doi ten bien, doi font chu & xu ly du lieu dan so
vn_pop_data %>%
rename(name = Name, status = Status, pop = `PopulationCensus2009-04-01`) %>%
mutate(name = stri_trans_general(name, "Latin-ASCII")) %>%
mutate(pop = str_replace_all(pop,",","")) %>%
mutate(pop = as.numeric(pop)) %>%
mutate(pop = pop/1000) -> vn_pop_data
# Filter du lieu cap tinh va cap huyen
vn_pop_data %>% filter(status %in% c("Municipality", "Province")) -> province_pop_data
vn_pop_data %>% filter(str_detect(status, "District")) -> district_pop_dataBước 2. Load dữ liệu bản đồ
# Du lieu ban do cap tinh
province_map_data <- raster::getData(name = "GADM", country = "vietnam", level = 1) %>%
fortify(region = "NAME_1") %>%
mutate(name = stri_trans_general(id, "Latin-ASCII"))
# Du lieu ban do cap huyen
district_map_data <- raster::getData(name = "GADM", country = "vietnam", level = 2) %>%
fortify(region = "NAME_2") %>%
mutate(name = stri_trans_general(id, "Latin-ASCII"))Bước 3. Nối dữ liệu bản đồ với dữ liệu dân số
# Mot so tinh co ten khong khop nhau trong 2 bo du lieu
base::setdiff(province_pop_data$name, province_map_data$name %>% unique()) -> prov_diff
province_pop_data %>%
mutate(name = case_when(name == prov_diff[1] ~ "Ha Noi",
name == prov_diff[2] ~ "Ho Chi Minh",
name == prov_diff[3] ~ "Thua Thien Hue",
TRUE ~ name)) -> province_pop_data
# 19 huyen co ten khong khop nhau trong 2 bo du lieu. Hien tai ta bo qua van de nay.
# Noi du lieu ban do voi du lieu dan so theo ten tinh/huyen
full_join(province_map_data, province_pop_data, by = "name") -> df_provinces
full_join(district_map_data, district_pop_data, by = "name") -> df_districtsBước 4. Vẽ
library(viridis)
ggplot() +
geom_polygon(data = df_provinces, aes(x = long, y = lat, group = group, fill = pop), color = "grey80") +
theme_minimal() +
theme(axis.title = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank(),
panel.grid = element_blank()) +
labs(title = "Figure 1: Population Density in Vietnam By Provincial Level",
subtitle = "(per thousand people)",
caption = "Source: https://www.citypopulation.de/en/vietnam & GADM") +
scale_fill_viridis(direction = -1,
option = "viridis",
name = "Density")ggplot() +
geom_polygon(data = df_districts, aes(x = long, y = lat, group = group, fill = pop), color = "grey80") +
theme_minimal() +
theme(axis.title = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank(),
panel.grid = element_blank()) +
labs(title = "Figure 2: Population Density in Vietnam By District Level",
subtitle = "(per thousand people)",
caption = "Source: https://www.citypopulation.de/en/vietnam & GADM") +
scale_fill_viridis(direction = -1,
option = "magma",
name = "Density")