R语言是一种用于统计分析和图形表示的编程语言和软件环境,它提供了多种数据结构以存储和操作数据。这些数据结构包括向量、矩阵、数组、数据框、列表、因子、Tibble、环境、公式、调用以及表达式。
向量(Vector)
向量是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列:
my_matrix <- matrix(1:20, nrow = 5, ncol = 4)
在R语言中也可以使用向量来组成矩阵,在以下代码中byrow = FALSE
参数指定了矩阵的填充方式。当byrow = FALSE
时,矩阵将按列填充,即先填充第一列,然后是第二列,如果设置为byrow = TRUE
,则矩阵将按行填充。
dimnames = list(rnames, cnames)
参数用于给矩阵的行和列命名。rnames
向量作为行名;cnames
向量作为列名。这两个向量被组合成一个列表,成为dimnames
的参数值。
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,三行三列的二维数组:
my_array <- array(1:9, dim = c(3, 3))
以下代码为建立从1~24,三行四列的3维数组:
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年龄、姓名、性别数据框:
df <- data.frame(
id = 1:5,
name = c("小猪猪", "菲菲", "迷糊老师", "小呆呆", "超人强"),
age = c(15, 13, 55, 30, 14),
gender = c("Male", "Female", "Male", "Male", "Male")
)
可以使用str()
函数查看数据框
> 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" ...
使用$
符号可以访问并操作数据框中的列
> 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的成绩表
student <- list(
name = "GGBoy",
age = 15,
courses = c("Math", "Stats", "Computer"),
grades = c(9, 12, 3),
gender = "Male"
)
添加新的元素到列表中 :
student$major <- "Data Science"
使用lapply()
函数对列表中的每个元素应用函数计算每个元素的长度
lapply_result <- lapply(student_info, length)
print(lapply_result)
输出如下:
$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()
函数对数据进行因子化。
my_factor <- factor(c("北京", "上海", "天津", "北京", "上海"))
在查看因子结构时即可看到 “北京”, “上海”, “天津” 被进行了因子化变成了 1, 2, 3
# 查看因子结构
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
包来进行操作:
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
),提供了许多便捷的操作方法,具有更严格的子集操作。
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如下:
在有些情况下在导包的时候会产生报的兼容警报:
> 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
包来管理冲突即可:
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() 相反的操作 |