R语言与数据科学教育:如何培养学生数据分析技能
作者:禅与计算机程序设计艺术
随着云计算、大数据、机器学习、深度学习等技术的普及,数据分析已经成为各行各业不可或缺的一环。但在这个全新的时代背景下,如何让学生掌握R语言和进行数据分析能力培养是一个重要课题。基于此,我们设计了一系列课程和项目,帮助学生更好地理解、掌握R语言、运用统计方法进行数据分析并对其进行应用。本次课程将通过简明易懂的讲解方式,引导学生在自学过程中快速入门R语言,逐步提升数据分析能力。
2.基本概念术语说明
为了方便读者阅读本教程,我们定义一些基础的概念和术语。
数据科学概述
数据科学(英文Data Science)是指利用数据进行观察、理解、分类和预测的一门学术研究领域。它涉及计算机、统计学、生物学、社会学、数学、工程学等多个学科的交叉领域,从事数据收集、处理、分析、可视化等整个生命周期的过程,并在此过程中开发出能够解决复杂问题的模型和工具。数据科学拥有以下五个主要特征:
- 可观测性(Observability):从数据源头(包括实验室、网络、商业数据库、政策制定机构、生活习惯和个人数据等)获取原始数据,以便理解数据的产生和作用。
- 理解性(Understanding):理解数据内部结构、模式、规律,做到数据的完整性、准确性、有效性。
- 汇总性(Aggregation):将数据汇集成用于决策的最终信息,并清洗无效信息。
- 模型化(Modelling):运用数据科学的理论与工具建立数据模型,对现实世界进行建模和预测。
- 实现性(Actionable Insights):将数据科学的分析结果转化成实际可执行的产品,供目标群体使用。
R语言概述
R语言是一种开源的语言和软件环境,广泛用于数据处理、统计分析和图形展示。它由R Core Team开发,是S-PLUS、TIBCO、Northwestern University等知名大学、组织开发,并获得了自由软件基金会的支持。目前,R语言已逐渐成为数据科学和数据分析领域的主流语言。R语言的版本众多,包括系统级R语言和轻量级R语言,其中系统级R语言包含交互式的R命令终端和RStudio集成开发环境。
数据分析的主要流程
数据分析的主要流程一般分为以下几个步骤:
- 数据采集:获取所需的数据,并进行数据的导入、清洗、整理、转换等工作,得到一个干净、可用的数据集。
- 数据探索:对数据进行初步的了解,通过绘图等工具对数据进行可视化,找出数据中的关键点,进而对数据进行初步的描述。
- 数据整理:根据业务需求、分析目的和分析方法对数据进行重新组织,使之变得适合分析。
- 数据建模:采用统计模型对数据进行建模,为数据提供预测模型,并对模型结果进行验证。
- 数据可视化:将数据以图表形式呈现出来,方便对数据进行分析和理解。
- 数据输出:将数据保存为文件或数据库,并按照要求进行输出。
图1:数据分析的主要流程
3.核心算法原理和具体操作步骤以及数学公式讲解
数据类型
R语言中常用的基本数据类型包括:
- 字符型(character): 字符串类型, 使用单引号(')或者双引号("")括起来。如: "Hello World!"
- 数值型(numeric): 用于表示数字, 支持整数、浮点数、复数。如: 100, 3.14, 1 + 4i (1+4i即为复数)
- 逻辑型(logical): 布尔类型, 表示真值TRUE或假值FALSE。如: TRUE, FALSE
- 向量(vector): 一组相同类型的元素组成的数组, 通过方括号([])创建, 可以是同类型元素也可以不同类型元素。如: c(1, 2, 3), c("apple", "banana", "orange")
- 矩阵(matrix): 二维数组, 每一行都有相同数量的元素, 通过大括号({})创建, 矩阵可以是同类型元素也可以不同类型元素。如: matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3)
- 数据框(data frame): 表格型数据结构, 每一列都有不同的类型, 可以是同类型元素也可以不同类型元素, 可以有行名和列名。如: data.frame(name = c("John", "Mary"), age = c(25, 30))
这些基本数据类型都可以使用函数class()查看自己的类别。
创建变量
在R语言中,使用符号<-或=来创建变量。创建变量后,可以通过变量名访问变量的值。
# 方式1:使用 <- 或 = 来赋值
x <- 1 # x 为 numeric 类型
y <- 'hello' # y 为 character 类型
# 方式2:使用 assign() 函数赋值
assign('z', 'world') # z 为 character 类型
当试图将变量值赋给不存在的变量时,R语言会自动创建该变量。
x <- 1
y <- a # ERROR! 不存在的变量 a ,此时 R 会自动创建变量 a 。
注释
R语言的注释采用 # 作为开头。单行注释只能注释单行,块注释可以注释多行。
# 这是单行注释
/*
这是块注释,
可以跨越多行。
*/
运算符
R语言支持常见的算术运算符、关系运算符、逻辑运算符、赋值运算符、条件运算符、成员运算符等。
算术运算符
| 操作符 | 描述 | 实例 | ||||
|---|---|---|---|---|---|---|
+ |
加法运算 | 2 + 3 返回 5 |
||||
- |
减法运算 | 2 - 3 返回 -1 |
||||
* |
乘法运算 | 2 * 3 返回 6 |
||||
/ |
除法运算 | 2 / 3 返回 0.666667 |
||||
^ |
幂运算 | 2 ^ 3 返回 8 |
||||
%/% |
取整除法运算 | 5 %/% 2 返回 2,-5 %/% 2 返回 -3 |
||||
%% |
余数运算 | 5 %% 2 返回 1,-5 %% 2 返回 1 |
||||
> |
大于运算 | 3 > 2 返回 TRUE |
||||
< |
小于运算 | 3 < 2 返回 FALSE |
||||
>= |
大于等于运算 | 3 >= 2 返回 TRUE |
||||
<= |
小于等于运算 | 3 <= 2 返回 FALSE |
||||
== |
等于判断运算符 | "abc" == "abc" 返回 TRUE |
||||
!= |
不等于判断运算符 | "abc"!= "def" 返回 TRUE |
||||
& |
逻辑与运算 | TRUE & TRUE 返回 TRUE |
||||
| ` | ` | 逻辑或运算 | `TRUE | FALSE返回TRUE` |
||
! |
逻辑否运算 | !FALSE 返回 TRUE |
||||
&& |
短路逻辑与运算 | x && NULL 当 x 为NULL 时返回 NULL |
||||
| ` | ` | 短路逻辑或运算 | `x | NA_integer_` 当 x 为NA 时返回 NA |
关系运算符
| 操作符 | 描述 | 实例 |
|---|---|---|
== |
检查两个对象是否相等 | 1 == 1 返回 TRUE, 2 == 1 返回 FALSE |
!= |
检查两个对象是否不相等 | 1!= 1 返回 FALSE, 2!= 1 返回 TRUE |
> |
检查左边的对象是否大于右边的对象 | 2 > 1 返回 TRUE |
< |
检查左边的对象是否小于右边的对象 | 2 < 1 返回 FALSE |
>= |
检查左边的对象是否大于等于右边的对象 | 2 >= 2 返回 TRUE |
<= |
检查左边的对象是否小于等于右边的对象 | 2 <= 2 返回 TRUE |
逻辑运算符
| 操作符 | 描述 | 实例 | ||
|---|---|---|---|---|
& |
逻辑且运算 | (1 == 1) & (2 == 2) 返回 TRUE |
||
| ` | ` | 逻辑或运算 | `(1 == 1) | (2 == 2)返回TRUE` |
! |
逻辑非运算 | !(1 == 1) 返回 FALSE |
||
&& |
短路逻辑与运算 | if (!is.null(x)) { expr } 当 x 不为NULL 时返回 expr 的值 |
||
| ` | ` | 短路逻辑或运算 | if (any(!is.na(x))) { expr } 当 x 中有非 NA 值时返回 expr 的值 |
赋值运算符
| 操作符 | 描述 | 实例 |
|---|---|---|
<- |
从右边的值赋给左边的变量 | x <- 1 将变量 x 的值为 1 |
-> |
从右边的值赋给左边的变量(R 版本 >= 3.5.0) | f <- function(...) {...} 将表达式的值赋给函数 f |
条件运算符
| 操作符 | 描述 | 实例 |
|---|---|---|
? |
提示帮助文档 | ?mean |
ifelse |
根据条件选择相应的表达式 | result <- ifelse(age>18,"adult","teenager") 如果 age > 18, result 为 "adult",否则为 "teenager" |
成员运算符
| 操作符 | 描述 | 实例 |
|---|---|---|
%in% |
检查左边的对象是否属于右边的集合 | "b" %in% c("a", "b", "c") 返回 TRUE |
: |
创建一个范围序列 | 1:5 返回 [1, 2, 3, 4, 5] |
数学函数
R语言内置的很多数学函数非常有用,这里只介绍一些常用的函数。 | 函数名称 | 描述 | | --- | --- | | abs() | 返回绝对值 | | sqrt() | 返回平方根 | | exp() | 返回e的指数 | | log() | 以e为底的对数 | | sin(), cos(), tan() | 返回正弦、余弦、正切值 | | asin(), acos(), atan() | 返回反正弦、反余弦、反正切值 | | round() | 对数值四舍五入 | | max(), min(), sum(), mean(), median(), sd() | 求最大值、最小值、求和、均值、中位数、标准差 |
控制语句
R语言支持if-else语句,for循环语句,while循环语句。
if-else语句
if-else语句的语法如下:
if (条件1){
表达式1
} else if (条件2){
表达式2
} else{
表达式3
}
比如:
# 判断年龄是否大于18岁
age <- as.numeric(readline(prompt="请输入你的年龄:"))
if (age > 18) {
message("你今年已满18岁!")
} else {
message("你还未满18岁!")
}
for循环语句
for循环语句的语法如下:
for (变量 in 值1:值2){
循环体
}
比如:
for (i in seq_len(10)){
print(i)
}
while循环语句
while循环语句的语法如下:
while (条件){
循环体
}
比如:
num <- 1
while (num <= 10){
cat(num, "
")
num <- num + 1
}
处理数据
R语言可以处理各种各样的数据,包括结构化数据和半结构化数据,下面介绍几种常用的处理数据的方法。
文件读取
R语言提供了多种方式读取文件,包括直接读取文本文件、CSV文件、Excel文件等,下面是读取文本文件的例子:
# 读取文本文件
myfile <- file("example.txt", open = "r")
text <- readLines(myfile)
close(myfile)
读取CSV文件需要使用read.csv()函数,参数指定 CSV 文件路径。
# 读取CSV文件
myfile <- file("example.csv", open = "r")
data <- read.csv(myfile)
close(myfile)
读取Excel文件需要安装readxl包,然后使用read_excel()函数读取 Excel 文件。
# 安装和加载readxl包
install.packages("readxl")
library(readxl)
# 读取Excel文件
myfile <- "example.xlsx"
data <- read_excel(myfile)
数据合并
如果多个数据集之间存在相同的字段,可以通过合并操作来避免重复。
# 创建数据集1
set1 <- data.frame(id=c(1:5), name=c("Alice", "Bob", "Charlie", "David", "Emily"))
# 创建数据集2
set2 <- data.frame(id=c(3:5), gender=c("Male", "Female", "Male"), city=c("New York", "Chicago", "Los Angeles"))
# 数据合并
mergedSet <- merge(set1, set2, by.x="id", by.y="id")
print(mergedSet)
上面的例子中,merge()函数的第一个参数是数据集1,第二个参数是数据集2,第三个参数是用来匹配的键。
数据转换
R语言提供了许多函数可以对数据进行转换,比如把字符型转换为数值型,把列表转换为数据框,等等。
# 把字符型转换为数值型
x <- "3"
as.numeric(x) # Output: [1] 3
# 把列表转换为数据框
list <- list(name=c("Alice", "Bob", "Charlie"), age=c(25, 30, 35))
df <- data.frame(unlist(list))
names(df)<- names(list)
print(df)
数据聚合
R语言提供了aggregate()函数对数据进行聚合。
# 创建数据集
mydata <- data.frame(
id=c(1, 1, 2, 2, 3, 3),
value=c(2, 3, 5, 7, 11, 13)
)
# 对数据集进行聚合
aggdata <- aggregate(value ~ id, mydata, mean)
print(aggdata)
上面例子中,aggregate()函数的第一个参数是需要聚合的变量,第二个参数是数据集,第三个参数是聚合函数。
数据过滤
R语言提供了许多函数可以对数据进行过滤,比如删除空值、按条件筛选等。
# 删除空值
mydata[complete.cases(mydata), ]
# 按条件筛选
filter(mydata, value > 5)
数据可视化
R语言支持丰富的数据可视化功能,包括柱状图、箱线图、散点图、条形图、直方图等。
柱状图
R语言提供的最简单的数据可视化就是柱状图,通过函数barplot()可以快速绘制。
# 生成数据
values <- c(22, 25, 21, 23, 26, 20, 24)
groups <- c("A", "A", "B", "B", "C", "C", "D")
# 绘制柱状图
barplot(height = values,
names.arg = groups,
main = "Sample Bar Chart",
xlab = "Groups",
ylab = "Values")
箱线图
R语言提供的箱线图函数是boxplot(),可以很方便地绘制箱线图。
# 生成数据
ages <- rnorm(100)
gender <- sample(c("Male", "Female"), size = 100, replace = T)
# 绘制箱线图
boxplot(ages~gender,
main = "Box Plot of Ages vs Gender",
xlab = "Gender",
ylab = "Ages",
col = c("#E74C3C", "#2ECC71"),
notch = F,
boxwex =.5)
散点图
R语言提供的散点图函数是scatterplot(),可以很方便地绘制散点图。
# 生成数据
x <- rnorm(100)
y <- runif(100)
# 绘制散点图
pairs(cbind(x,y))
条形图
R语言提供的条形图函数是barplot(),可以很方便地绘制条形图。
# 生成数据
numbers <- c(22, 25, 21, 23, 26, 20, 24)
categories <- c("A", "A", "B", "B", "C", "C", "D")
# 绘制条形图
barplot(numbers,
horiz = T,
names.arg = categories,
main = "Bar Chart of Numbers per Category",
xlab = "Categories",
ylab = "Numbers",
width = 0.5,
border = "blue",
space = 0)
直方图
R语言提供的直方图函数是hist(),可以很方便地绘制直方图。
# 生成数据
grades <- c(80, 75, 85, 90, 65, 95, 80, 85, 95, 70)
# 绘制直方图
hist(grades,
breaks = seq(from = min(grades)-1, to = max(grades)+1, length.out = 10),
freq = F,
main = "Histogram of Grades",
xlab = "Grades",
ylab = "Frequency",
col = "lightblue")
4.具体代码实例和解释说明
为了帮助读者更好地理解知识点,文章结尾部分提供一些具体的代码实例和解释说明,可以帮助读者更好地理解相关概念和应用场景。
数据导入导出
CSV文件导入
# 导入CSV文件
myfile <- "example.csv"
data <- read.csv(myfile)
CSV文件导出
# 导出CSV文件
write.csv(data, file="output.csv")
随机数生成
R语言内置的sample()函数可以生成随机数。
# 生成10个随机数
set.seed(123)
randNums <- sample(1:100, 10, replace = T)
正态分布
R语言内置的rnorm()函数可以生成正态分布随机数。
# 生成10个服从标准正态分布的随机数
set.seed(123)
normalRandNums <- rnorm(10)
卡方检验
R语言提供的chisq.test()函数可以进行卡方检验。
# 构造测试数据
testData <- c(12, 10, 8, 9, 8, 6, 12, 11, 10, 9, 10, 12, 11, 9, 9, 10, 8, 12)
# 执行卡方检验
myTestRes <- chisq.test(testData)
print(myTestRes$p.value)
