基于R语言的统计分析基础:数据结构

R语言是一种用于统计分析和图形表示的编程语言和软件环境,它提供了多种数据结构以存储和操作数据。这些数据结构包括向量、矩阵、数组、数据框、列表、因子、Tibble、环境、公式、调用以及表达式。

向量(Vector)

向量是R中最基本的数据结构,是用于存储相同类型数据元素的一维数组。向量可以使可以是数值型、字符型或逻辑型等,但是同一向量无法混杂不同类型或模式的数据

r 复制代码
# 数值型向量
a <- c(1,2,3,4,5)
# 字符型向量
b <- c("猪猪侠","菲菲猪","超人强")
# 逻辑型向量
c <- c(TRUE, FALSE, FALSE)

# 只包含一个元素的向量叫做 标量(scalar)
d <- 1 # 数值型标量
f <- "GGBond"  # 字符型标量
g <- TRUE  # 逻辑型标量

在RStudio的环境窗口中可以清楚地看到这些向量和它们的类型

矩阵(Matrix)

矩阵是二维的矩形数据集,其中每个元素都具有相同的数据类型。矩阵在R中可以使用matrix()函数创建,用于存储和操作数学矩阵。

以下代码是matrix()函数的最基础用法,在函数中1:20表示创建从1~20的向量,nrow = 5表示矩阵为5行,ncol = 4表示矩阵为4列:

r 复制代码
my_matrix <- matrix(1:20, nrow = 5, ncol = 4)

在R语言中也可以使用向量来组成矩阵,在以下代码中byrow = FALSE参数指定了矩阵的填充方式。当byrow = FALSE时,矩阵将按列填充,即先填充第一列,然后是第二列,如果设置为byrow = TRUE,则矩阵将按行填充。
dimnames = list(rnames, cnames)参数用于给矩阵的行和列命名。rnames向量作为行名;cnames向量作为列名。这两个向量被组合成一个列表,成为dimnames的参数值。

r 复制代码
cells <- c(1, 3, 5, 7)
rnames <- c("r1", "r2")
cnames <- c("c1", "c2")
my_matrix2 <- matrix(cells, nrow = 2, ncol = 2,
                        byrow = TRUE, dimnames = list(rnames, cnames))
my_matrix3 <- matrix(cells, nrow = 2, ncol = 2,
                        byrow = FALSE, dimnames = list(rnames, cnames))

如果是在RStudio中查看矩阵,可以使用View()函数,RStudio会弹出数据框显示矩阵

查看或修改矩阵中参数也很方便,比如查询矩阵第二行第三列的数值,随后将数值更改为12:

R语言中的矩阵操作方法表格如下:

矩阵操作方法 描述
matrix(data, nrow, ncol) 使用数据创建一个矩阵,data是矩阵中的元素,nrow是行数,ncol是列数
dim(matrix) 返回矩阵的维度,即行数和列数
matrix[i, j] 访问矩阵中第i行第j列的元素
matrix[i, ] 访问矩阵中的第i
matrix[, j] 访问矩阵中的第j
matrix[i, j] <- value 将矩阵中第i行第j列的元素修改为value
rowSums(matrix) 计算矩阵的每一行的和
colSums(matrix) 计算矩阵的每一列的和
rowMeans(matrix) 计算矩阵的每一行的均值
colMeans(matrix) 计算矩阵的每一列的均值
rbind(matrix1, matrix2) 按行合并矩阵
cbind(matrix1, matrix2) 按列合并矩阵
t(matrix) 返回矩阵的转置
%*% 矩阵乘法
+-*/ 矩阵的加、减、乘(元素乘法)、除运算
solve(matrix) 计算矩阵的逆
det(matrix) 计算矩阵的行列式
eigen(matrix) 计算矩阵的特征值和特征向量

数组(Array)

在R语言中可以存储多维数据,每个元素具有相同的数据类型。数组可以是二维矩阵,也可以是更高维度的,数组可以使用array()函数创建数组。

以下代码创建了一个从1~9,三行三列的二维数组:

r 复制代码
my_array <- array(1:9, dim = c(3, 3))

以下代码为建立从1~24,三行四列的3维数组:

r 复制代码
my_3d_array <- array(1:24, dim = c(3, 4, 2))

R语言中的数组操作方法表格如下:

序号 操作方法 描述
1 matrix() 创建矩阵,通过指定数据、行数、列数等参数来生成矩阵
2 dim() 设置或获取矩阵的维数(行数和列数)
3 nrow() 获取矩阵的行数
4 ncol() 获取矩阵的列数
5 [行索引, 列索引] 访问矩阵中特定位置的元素或子集
6 +, -, *, / 对矩阵进行基本的算术运算(加、减、乘、除),注意矩阵乘法使用%*%
7 %*% 矩阵乘法,要求左侧矩阵的列数等于右侧矩阵的行数
8 t() 矩阵转置,将矩阵的行和列互换
9 det() 计算方阵的行列式值
10 solve() 求解方阵的逆矩阵
11 eigen() 计算矩阵的特征值和特征向量
12 colSums() 计算矩阵每列的和
13 rowSums() 计算矩阵每行的和
14 colMeans() 计算矩阵每列的均值
15 rowMeans() 计算矩阵每行的均值
16 diag() 提取矩阵的对角线元素或生成对角矩阵/单位矩阵
17 lower.tri()upper.tri() 分别用于提取矩阵的下三角和上三角部分
18 cbind() 按列合并矩阵或向量
19 rbind() 按行合并矩阵或向量
20 as.matrix() 将数据框(data.frame)或其他类型的数据转换为矩阵

数据框(Data Frame)

数据框 用于存储表格型数据,其中每列可以包含不同类型的数据(数值、字符、逻辑等),数据框通常使用data.frame()函数创建。

以下代码创建了一个GGBond年龄、姓名、性别数据框:

r 复制代码
df <- data.frame(  
     id = 1:5,  
     name = c("小猪猪", "菲菲", "迷糊老师", "小呆呆", "超人强"),  
     age = c(15, 13, 55, 30, 14),  
     gender = c("Male", "Female", "Male", "Male", "Male")  
 ) 

可以使用str()函数查看数据框

r 复制代码
> str(df) 
'data.frame':	5 obs. of  4 variables:
 $ id    : int  1 2 3 4 5
 $ name  : chr  "小猪猪" "菲菲" "迷糊老师" "小呆呆" ...
 $ age   : num  15 13 55 30 14
 $ gender: chr  "Male" "Female" "Male" "Male" ...

使用$符号可以访问并操作数据框中的列

r 复制代码
> print(df$name)
[1] "小猪猪"   "菲菲"     "迷糊老师" "小呆呆"   "超人强"  
> df$score <- c(85, 90, 88, 95, 92)  # 添加一列名为 score 的列
> df$score <- NULL # 删除一列名为 score 的列

R语言中的数据框操作方法表格如下:

序号 操作方法 描述
1 data.frame() 创建数据框,可以将向量、列表等数据结构转换为数据框
2 str() 查看数据框的结构,包括变量名称、类型、长度等
3 head()tail() 查看数据框的前几行或后几行数据
4 $ 符号 或 [] 运算符 访问数据框的列或行
5 $ 符号 或 [] 运算符 添加新的列到数据框中
6 rbind()cbind() 添加新的行到数据框中,rbind()用于按行合并,cbind()用于按列合并
7 [] 运算符 选择数据框的子集,可以使用逻辑运算符或条件语句进行筛选
8 merge()dplyr::join() 将两个数据框按照某一列或条件进行合并
9 split() 根据数据框中选定列的不同取值将数据框拆分为多个子数据框
10 as.data.frame() 将其他数据结构(如列表、矩阵)转换为数据框
11 order()dplyr::arrange() 对数据框进行排序,order()返回排序后的索引,arrange()直接返回排序后的数据框
12 summary()mean()sd() 对数据框进行统计分析,如计算摘要统计信息、均值、标准差等
13 names() 查看或修改数据框的列名
14 subset() 根据条件选择数据框的子集
15 transform()within()dplyr::mutate() 在数据框中添加或修改列,这些函数提供了不同的方式来处理新列的计算
16 is.na()na.omit() 检查数据框中的缺失值,并移除含有缺失值的观测
17 apply() 系列函数 对数据框中的数据进行批量处理,如计算列的均值、中位数等
18 reshape2::melt()reshape2::dcast() 重塑数据框,从宽格式转换为长格式或从长格式转换为宽格式
19 dplyr 包中的管道操作 使用 %>% 符号进行数据框的管道操作,结合 select()filter()summarise() 等函数进行高效的数据处理

列表(List)

在R语言中列表(List)是一种复杂的数据结构。列表是一种递归的数据结构,可以包含不同类型的元素,如数值、字符串、向量、矩阵、数据框,甚至其他列表,列表允许用户组合多个对象,并对其进行操作。

以下代码使用list()函数创建了一个GGBoy的成绩表

r 复制代码
student <- list(  
     name = "GGBoy",  
     age = 15,  
     courses = c("Math", "Stats", "Computer"),  
     grades = c(9, 12, 3),  
     gender = "Male"  
) 

添加新的元素到列表中 :

r 复制代码
student$major <- "Data Science" 

使用lapply()函数对列表中的每个元素应用函数计算每个元素的长度

r 复制代码
lapply_result <- lapply(student_info, length)  
print(lapply_result)  

输出如下:

bash 复制代码
$name
[1] 1

$age
[1] 1

$courses
[1] 3

$grades
[1] 3

$gender
[1] 1

$major
[1] 1

R语言中的列表操作方法表格如下:

序号 操作方法 描述
1 list() 创建列表,可以包含不同类型和长度的对象
2 str() 查看列表的结构,包括列表内对象的名称和类型
3 $ 符号 通过列表元素的名称访问元素
4 [[ ]] 符号 通过索引(可以是数字或名称)访问列表元素的内容,返回元素本身类型
5 [ ] 符号 通过索引访问列表元素,返回的是列表的子列表
6 names() 查看或修改列表元素的名称
7 length() 获取列表的元素个数
8 赋值操作 修改列表元素的值,或向列表中添加新元素
9 NULL 赋值 通过将列表元素赋值为NULL来删除元素
10 c() 函数 可以用于合并多个列表,但请注意,这会扁平化列表(即不会保留原列表的结构)
11 lapply(), sapply(), vapply() 对列表中的每个元素应用函数,lapply()返回列表,sapply()vapply()尝试简化输出
12 unlist() 将列表中的元素转换为一个向量,可选地保留元素名称作为向量元素的名称
13 recursive = FALSE 参数 在使用unlist()时,通过设置recursive = FALSE参数来避免递归展开列表中的列表
14 list.files(), dir() 虽然不直接操作列表,但这些函数常用于获取文件名列表,随后这些列表可用于文件路径等列表操作

因子(Factor)

因子用于表示分类数据,因子在统计建模和图形表示中非常有用,因为可以表示具有有限数量可能值的变量,在语言中使用factor()函数对数据进行因子化。

r 复制代码
my_factor <- factor(c("北京", "上海", "天津", "北京", "上海")) 

在查看因子结构时即可看到 "北京", "上海", "天津" 被进行了因子化变成了 1, 2, 3

r 复制代码
# 查看因子结构  
str(gender_factor)  
# 查看因子的水平  
levels(gender_factor)  

R语言中的因子操作方法表格如下:

方法/函数 描述
factor() 创建因子。基本语法为factor(x, levels = NULL, labels = levels, exclude = NA, ordered = FALSE, nmax = NA),其中x是输入向量,levels指定因子水平,labels用于重命名水平,exclude排除特定值,ordered指定因子是否有序。
levels() 查看或设置因子的水平(类别)。例如,levels(my_factor)查看水平,levels(my_factor) <- c("A", "B", "C")重新设置水平。
as.numeric() 将因子转换为数值型向量,但注意这通常不是因子的原始数值索引,而是因子水平的顺序编号。
as.character() 将因子转换为字符型向量,即因子的标签。
recode() dplyr包中,用于重新编码因子的水平。需要加载dplyr包。
fct_recode() forcats包中,提供更为灵活的因子水平重编码功能。
fct_relevel() forcats包中,用于改变因子的水平顺序。
fct_drop() forcats包中,用于删除因子中未使用的水平。
fct_collapse() forcats包中,用于将多个因子水平合并为一个。
ordered() 创建有序因子。语法与factor()类似,但通过设置ordered = TRUE参数指定因子有序。
table() 用于生成因子的频数表,展示每个水平的观测数。
str() 查看数据结构的详细信息,对于因子,可以显示其水平和存储的整数编码。
tapply() 分组调用函数,根据因子的水平对向量进行分组,并对每组应用指定的函数。
split() 根据因子将向量或数据框分割成列表,每个列表元素包含对应因子水平的数据。
by() 根据一个或多个因子对数据框进行分组,并对每组应用指定的函数。

日期和时间(Date and Time)

R语言提供了处理和操作日期和时间的特殊数据类型,这些类型包括"Date"(日期)、"POSIXct"(日期和时间)和"POSIXlt"(日期和时间的列表表示)。

这里我使用了lubridate包来进行操作:

r 复制代码
library(lubridate)  

# 创建日期对象  
date1 <- as.Date("2023-04-01")  
date2 <- as.Date("2023/04/02")  

# 创建时间对象  
time1 <- as.POSIXct("2023-04-01 12:00:00")  
time2 <- as.POSIXct("2023-04-02 15:30:00", tz = "UTC")  

# 格式化日期和时间  
formatted_date <- format(date1, "%Y-%m-%d")  
formatted_time <- format(time1, "%Y-%m-%d %H:%M:%S")  

# 提取日期和时间的组成部分  
year_of_date <- year(date1)  
month_of_date <- month(date1)  
day_of_date <- mday(date1)  
hour_of_time <- hour(time1)  
minute_of_time <- minute(time1)  
second_of_time <- second(time1)  

# 日期时间计算  
date_diff <- difftime(date2, date1, units = "days")  
time_diff <- difftime(time2, time1, units = "hours")  

# 使用lubridate包进行日期时间操作  
today_date <- today()  
now_time <- now()  

# 解析不同格式的日期时间字符串  
parsed_date1 <- ymd("20230401")  
parsed_date2 <- mdy("04/02/2023")  
parsed_time <- ymd_hms("2023-04-01 12:00:00")  

# 提取和设置日期时间的年、月、日等  
extracted_year <- year(parsed_date1)  
parsed_date1_updated <- update(parsed_date1, year = 2024)  

# 日期时间的舍入  
rounded_date <- floor_date(parsed_date1, "month")  
rounded_time <- round_date(parsed_time, "hour")  

# 打印结果
cat("格式化日期:", formatted_date, "\n")  
cat("格式化时间:", formatted_time, "\n")  
cat("日期中的年份:", year_of_date, "\n")  
cat("日期差:", date_diff, "天\n")  
cat("时间差:", time_diff, "小时\n")  
cat("今天的日期:", today_date, "\n")  
cat("当前时间:", now_time, "\n")  
cat("解析的日期1:", parsed_date1, "\n")  
cat("解析的日期2:", parsed_date2, "\n")  
cat("解析的时间:", parsed_time, "\n")  
cat("提取的年份:", extracted_year, "\n")  
cat("更新的日期:", parsed_date1_updated, "\n")  
cat("四舍五入的日期:", rounded_date, "\n")  
cat("四舍五入的时间:", rounded_time, "\n")

脚本输出:

R语言中的日期和时间操作方法表格如下:

方法/函数 描述
as.Date() 将字符型或数值型数据转换为日期对象。默认格式为"YYYY-MM-DD"。
Sys.Date() 返回当前系统日期。
format() 将日期或时间对象按照指定的格式进行格式化。
weekdays() 返回日期对象的星期几名称。
months() 返回日期对象的月份名称。
quarters() 返回日期对象所在的季度。
Sys.time() 返回当前系统日期和时间。
as.POSIXct() 将日期时间字符串转换为POSIXct对象,后者以秒为单位自1970-01-01 UTC起算。
as.POSIXlt() 类似于as.POSIXct(),但返回的是一个列表,包含年、月、日等详细时间信息。
日期加减运算 日期对象可以与数值进行加减运算,表示日期的加减天数。
difftime() 计算两个日期或时间之间的差异,可以指定单位(如天、小时等)。
seq.Date()seq()(用于日期) 生成日期序列。可以通过设置起始日期、结束日期和步长来生成日期序列。
lubridate包函数 today()now()ymd()mdy()dmy()等,提供更方便的日期时间生成、解析和格式化功能。
year(), month(), mday() lubridate包中,用于提取日期时间对象的年、月、日等组成部分。
hour(), minute(), second() lubridate包中,用于提取时间对象的时、分、秒等组成部分。
floor_date(), round_date() lubridate包中,用于对日期进行向下或向上舍入到指定的时间单位(如天、月、年)。

Tibble

Tibble是tibble包提供的一种现代化的数据框,可以将tibble是一种优化的数据框(data.frame),提供了许多便捷的操作方法,具有更严格的子集操作。

r 复制代码
library(tidyverse)

# 创建一个tibble  
my_tibble <- tibble(  
  name = c("Alice", "Bob", "Charlie"),  
  age = c(25, 30, 35),  
  height = c(165, 175, 180)  
)  
  
# 打印tibble  
print(my_tibble)  
  
# 访问tibble中的name列  
print(my_tibble$name)  

# 使用dplyr包中的函数来操作tibble,筛选出年龄大于30的记录  
filtered_tibble <- my_tibble %>% filter(age > 30)  
print(filtered_tibble)  
  
# 在tibble中添加一列  
my_tibble <- my_tibble %>% mutate(weight = c(60, 70, 80))  
print(my_tibble)  
  
# 对tibble进行排序  
sorted_tibble <- my_tibble %>% arrange(desc(age))  
print(sorted_tibble)

初始创建的tibble如下:

经过操作后的tibble如下:

在有些情况下在导包的时候会产生报的兼容警报:

bash 复制代码
> library(tidyverse)
── Attaching core tidyverse packages ─────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr   1.1.4     ✔ readr   2.1.5
✔ forcats 1.0.0     ✔ stringr 1.5.1
✔ ggplot2 3.5.1     ✔ tibble  3.2.1
✔ purrr   1.0.2     ✔ tidyr   1.3.1
── Conflicts ───────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package to force all conflicts to become errors

这时使用conflicted包来管理冲突即可:

bash 复制代码
library(conflicted)
conflict_prefer("filter", "dplyr")
conflict_prefer("lag", "dplyr")

R语言中的tibble操作方法表格如下:

方法名 描述 示例代码
tibble() 创建一个新的tibble,输入可以是向量、列表等 tibble(name = c("Alice", "Bob"), age = c(25, 30))
as_tibble() 将其他类型的数据结构(如data.frame、list)转换为tibble as_tibble(iris)as_tibble(list(a = 1:5, b = letters[1:5]))
$ 提取tibble中的某一列 my_tibble$name
[[ 类似$,但可用于编程方式提取列,特别是当列名存储在变量中时 my_tibble[["name"]]
%>% 管道操作符,将左侧对象传递给右侧函数的第一个参数 my_tibble %>% filter(age > 30)
filter() 从tibble中筛选出满足条件的行(dplyr包) my_tibble %>% filter(age > 30)
select() 选择tibble中的列(dplyr包) my_tibble %>% select(name, age)
mutate() 在tibble中添加新列或修改现有列(dplyr包) my_tibble %>% mutate(weight = age * 10)
arrange() 对tibble中的行进行排序(dplyr包) my_tibble %>% arrange(desc(age))
group_by() 对tibble中的行进行分组,以便后续进行汇总操作(dplyr包) my_tibble %>% group_by(age) %>% summarise(mean_height = mean(height))
summarise() 对分组后的tibble进行汇总计算(dplyr包) 同上例中的summarise()部分
slice() 选择tibble中的行(dplyr包),可以按位置选择或基于条件选择 my_tibble %>% slice(1:2)my_tibble %>% slice(which(age > 30))
rename() 重命名tibble中的列(dplyr包) my_tibble %>% rename(Name = name, Age = age)
pivot_longer() 将tibble从宽格式转换为长格式(tidyr包,tidyverse的一部分) my_tibble %>% pivot_longer(cols = c(age, height), names_to = "attribute", values_to = "value")
pivot_wider() 将tibble从长格式转换为宽格式(tidyr包,tidyverse的一部分) pivot_longer()相反的操作
相关推荐
ac-er8888几秒前
PHP网络爬虫常见的反爬策略
开发语言·爬虫·php
爱吃喵的鲤鱼10 分钟前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
懒惰才能让科技进步33 分钟前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
DARLING Zero two♡37 分钟前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
Gu Gu Study39 分钟前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言
Ni-Guvara1 小时前
函数对象笔记
c++·算法
芊寻(嵌入式)1 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
一颗松鼠1 小时前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
泉崎1 小时前
11.7比赛总结
数据结构·算法
有梦想的咸鱼_1 小时前
go实现并发安全hashtable 拉链法
开发语言·golang·哈希算法