R语言学习:长宽数据转换、研究生学习R指南、特征重要性分析、文件合并
2021年第36周。
这一周R语言学习,记录如下。
01
R语言相关书籍
本周分享4本R语言书籍,每本书都有所长和特色,也有自己的规划和设计。请挑选适合自己的系列。
(获取方式:进入R语言公众号,发送消息202136)
02
长宽数据转换
长数据转换为宽数据,是一种增加列数,减少行数的数据处理操作,可用于特征生成;宽数据转换为长数据,是一种增加行数,减少列数的数据处理操作,可利于数据可视化处理。
使用tidyr包
1 pivot_wider()函数,长数据–>宽数据
2 pivot_longer()函数,宽数据–>长数据
library(tidyr)
library(magrittr)
# 1 长数据--> 宽数据
fish_encounters %>% View
names(fish_encounters)
sapply(fish_encounters, class)
fish_encounters %>%
pivot_wider(names_from = station,
values_from = seen) %>%
View
# 参数values_fill进行缺失值处理
fish_encounters %>%
pivot_wider(names_from = station,
values_from = seen,
values_fill = 0) %>%
View
# 值的来源,也可以是多个变量
us_rent_income %>% View
names(us_rent_income)
us_rent_income %>%
pivot_wider(names_from = variable,
values_from = c(estimate, moe)) %>%
View
# 2 宽数据-->长数据
relig_income %>% View
names(relig_income)
sapply(relig_income, class)
relig_income %>%
pivot_longer(-religion,
names_to = "income",
values_to = "count") %>%
View
代码的结果,可以自己运行下,对比观察下转换前后的结果差异。
03
研究生学习R语言指南
许多研究生朋友,做科研、写论文,会用到R语言。
这周在网上发现了一位神经科学领域的博士写的一本《研究生学习R语言指南》,送给需要的你。
访问网址:
https://bookdown.org/yih_huynh/Guide-to-R-Book/
正如作者所言。
“尽管有许多关于 R 的精彩指南/教科书,但其中很少有与我的特定需求相关的示例,并且对真正的初学者来说足够友好。作者开始在她的实验室教一名新研究生学习R。然而,我很快发现教授 R——即使只是一个人——非常耗时。我决定将作业写成 R 的“简短”指南。在写了 11 页的“第一次作业”并收到积极反馈后,我开始编写第二次作业。然后第三个。很快,我写了足够多的页数,我无法否认这个“简短指南”已经变成了一本书。直到今天,我还在不断学习在 R 中管理我的数据的新技术,并将我所知道的传授给任何想要学习的人。我坚信在研究生院学习处理数据的有效技术至关重要。教授 R 是我真正喜欢做的事情,我希望你发现这本书对你学习R有用。”
学习建议:
1 耐心学习,积极实践
2 认真完成每章节的习题
3 充分利用R语言来完成科研任务。
04
特征重要性分析和可视化
利用随机森林算法分析特征的重要性
利用ggplot2包对特征重要性做可视化分析
# R包
library(readxl)
library(dplyr)
library(ggplot2)
library(randomForest)
library(varImp)
library(caret)
# 数据导入
df <- read_excel("./raw_data/cpi.xlsx")
names(df)
# 构建RF模型
rf <- train(CPI ~ funding_rate+exchange_rate+CDS,
data = df,
method = "rf",
trControl = trainControl(method = "oob"),
importance = TRUE,
verbose = TRUE)
i_scores <- varImp(rf$finalModel, conditional=TRUE)
i_scores <- i_scores %>% tibble::rownames_to_column("var")
i_scores$var<- i_scores$var %>% as.factor()
# 特征重要性可视化
i_bar <- ggplot(data = i_scores) +
geom_bar(
stat = "identity",
mapping = aes(x = var, y=Overall, fill = var),
show.legend = FALSE,
width = 1
) +
labs(x = NULL, y = NULL)
i_bar + coord_polar() + theme_minimal()
i_bar + coord_flip() + theme_minimal()
可视化结果
参考资料:
Feature Importance in Random Forest
05
MAPE指标
最近做一个回归类的项目,为了便于理解和业务解释性,采用了MAPE做模型性能的度量和评价,对测试集验证和时间外样本(OOT)验证。
MAPE计算公式
MAPE = (1/n) * Σ(|Actual – Predicted| / |Actual|) * 100
MAPE计算示例
data <- data.frame(actual=c(44, 47, 34, 47, 58, 48, 46, 53, 32, 37, 26, 24),
pred=c(44, 40, 46, 43, 46, 58, 45, 44, 53, 30, 32, 23))
data
# 计算方法1
mean(abs((data$actual-data$pred)/data$actual)) * 100
# 计算方法2
library(MLmetrics)
MAPE(data$pred, data$actual) * 100
06
多个同变量的csv文件合并
场景:多个同变量的csv文件或者变体格式的文件合并和整合。
graphics.off()
rm(list = ls())
path<- file.path(getwd())
v.filename <- list.files(
path, pattern="\.(csv|txt)$",
ignore.case = TRUE,
full.names = FALSE)
# 方式一
df.all <- do.call(
rbind, lapply(v.filename,
function(x) read.csv(x)))
print(df.all)
# 方式二
library(vroom)
df.all.vroom <- vroom(v.filename)
print(df.all.vroom)
学习资料:
https://kiandlee.blogspot.com/2021/09/basic-r-read-so-many-csv-files.html
07
可重复性代码构建指南
创建项目工程,做项目管理
项目的层级架构,参考下图:
各个文件夹和文件的用途
请注意
1 永远不要修改原始数据,或者说,一定要备份好原始数据
2 对于任何项目,创建一个文件,记录你的所思和所做,便于复盘和迭代
3 脚本的命名,请知名晓意,赋予含义,具有条理性和逻辑性,重视代码的可读性,代码是让电脑来运行的,更重要的是,让人来看的。
4 对于一个复杂的项目,编写代码之前,先写伪代码或者画流程图
08
行名设置为数据集的一列
场景:有时候,需要给数据集增加一列行名,便于对样本做标签化管理
函数:tibble包的rownames_to_column函数
library(tibble)
df <- data.frame(A = c(1, 2, 3), B = c(10, 20, 30))
row.names(df) <- c("A", "B", "C")
(df)
df <- df %>% tibble::rownames_to_column("row_name")
(df)
08
快捷键
目的:提升工作效率
代码格式化:Ctrl + Shift + A
生成函数:Ctrl + Alt + X (需要先选中一些代码)
呈现所有面板:Ctrl + Alt + Shift + 0
编辑器面板:Ctrl + Shift + 1
控制台面板:Ctrl + Shift + 2
光标调到源代码:Ctrl + 1
光标移到控制台:Ctrl + 2
光标移到帮助:Ctrl + 1
09
sapply函数传递多个参数
向量化处理,使用含有多个参数的函数
mix_func <- function(a, b, c) {
a + b * c
}
x <- c(1,5,10)
sapply(x, mix_func, a = 1, b = 2)
10
数据合规性问题挖掘
2021年9月1日,《数据安全法》实施
数据合法合规的前提下,进行学习和应用,会是趋势,并会有法可依。
options(warn = -1)
options(scipen = 999)
library(tidyverse)
library(ggbeeswarm)
library(tidymodels)
# 01 数据合规性分析
# 2021年9月1日数据安全法实施
# 数据合规性监管
# GDPR 通用数据保护条例
write_csv(gdpr_raw, './raw_data/gdpr_raw.csv')
gdpr_raw
# 探索数据
# 1) 罚款的分布
# 严重有偏数据,采用对数变换,正态分布或者近似正态分布
gdpr_raw %>%
ggplot(aes(price + 1)) +
geom_histogram(fill = "midnightblue", alpha = 0.7) +
scale_x_log10(labels = scales::dollar_format(prefix = "€")) +
labs(x = "GDPR fine (EUR)", y = "GDPR violations") +
theme_classic()
gdpr_raw %>%
ggplot(aes(price + 1)) +
geom_histogram(fill = "midnightblue", alpha = 0.7) +
labs(x = "GDPR fine (EUR)", y = "GDPR violations") +
theme_classic()
# 数据整洁
# 数据嵌套操作的处理 unnest
# 数据生成新的列 transmute
# 函数化编程 map系列函数
gdpr_tidy <- gdpr_raw %>%
transmute(id,
price,
country = name,
article_violated,
articles = str_extract_all(article_violated, "Art.[:digit:]+|Art. [:digit:]+")
) %>%
mutate(total_articles = map_int(articles, length)) %>%
unnest(articles) %>%
add_count(articles) %>%
filter(n > 10) %>%
select(-n)
gdpr_tidy
gdpr_tidy %>%
dplyr::mutate(
articles = str_replace_all(articles, "Art. ", "Article "),
articles = fct_reorder(articles, price)
) %>%
ggplot(aes(articles, price + 1, color = articles, fill = articles)) +
geom_boxplot(alpha = 0.2, outlier.colour = NA) +
geom_quasirandom() +
scale_y_log10(labels = scales::dollar_format(prefix = "€")) +
labs(
x = NULL, y = "GDPR fine (EUR)",
title = "GDPR fines levied by article",
subtitle = "For 250 violations in 25 countries"
) +
theme(legend.position = "none")
# 模型构建
gdpr_violations <- gdpr_tidy %>%
mutate(value = 1) %>%
select(-article_violated) %>%
pivot_wider(
names_from = articles, values_from = value,
values_fn = list(value = max), values_fill = list(value = 0)
) %>%
janitor::clean_names()
gdpr_violations %>% View
gdpr_rec <- recipe(price ~ ., data = gdpr_violations) %>%
update_role(id, new_role = "id") %>%
step_log(price, base = 10, offset = 1, skip = TRUE) %>%
step_other(country, other = "Other") %>%
step_dummy(all_nominal()) %>%
step_zv(all_predictors())
gdpr_prep <- prep(gdpr_rec)
gdpr_prep
gdpr_wf <- workflow() %>%
add_recipe(gdpr_rec) %>%
add_model(linear_reg() %>%
set_engine("lm"))
gdpr_wf
gdpr_fit <- gdpr_wf %>%
fit(data = gdpr_violations)
gdpr_fit
# 数据结果展示
gdpr_fit %>%
pull_workflow_fit() %>%
tidy() %>%
arrange(estimate) %>%
knitr::kable()
# 探索模型结果
# 生成测试样例数据集
new_gdpr <- crossing(
country = "Other",
art_5 = 0:1,
art_6 = 0:1,
art_13 = 0:1,
art_15 = 0:1,
art_32 = 0:1
) %>%
mutate(
id = row_number(),
total_articles = art_5 + art_6 + art_13 + art_15 + art_32
)
new_gdpr %>% View
# 模型应用和预测
mean_pred <- predict(gdpr_fit,
new_data = new_gdpr
)
conf_int_pred <- predict(gdpr_fit,
new_data = new_gdpr,
type = "conf_int"
)
gdpr_res <- new_gdpr %>%
bind_cols(mean_pred) %>%
bind_cols(conf_int_pred)
gdpr_res %>% View
# 违反每种类型下GDPR罚款预期
gdpr_res %>%
filter(total_articles == 1) %>%
pivot_longer(art_5:art_32) %>%
filter(value > 0) %>%
mutate(
name = str_replace_all(name, "art_", "Article "),
name = fct_reorder(name, .pred)
) %>%
ggplot(aes(name, 10^.pred, color = name)) +
geom_point(size = 3.5) +
geom_errorbar(aes(
ymin = 10^.pred_lower,
ymax = 10^.pred_upper
),
width = 0.2, alpha = 0.7
) +
labs(
x = NULL, y = "Increase in fine (EUR)",
title = "Predicted fine for each type of GDPR article violation",
subtitle = "Modeling based on 250 violations in 25 countries"
) +
scale_y_log10(labels = scales::dollar_format(prefix = "€", accuracy = 1)) +
theme(legend.position = "none")
部分结果
学习资料:
https://juliasilge.com/blog/gdpr-violations/
我创建了R语言群,添加我的微信,备注:姓名-入群,我邀请你进群,一起学习R语言。
如果你觉得文章内容有用,请关注下方公众号~
如果你想找数据工作,请关注下方公众号~
R语言学习专辑:
觉得本文不错,就顺手帮我转发到朋友圈和微信群哦,谢谢。
请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!