一、前言
在R语言中,tidyverse
是一个庞大的数据分析生态系统,它由一系列数据可视化和数据处理软件包组成,能够极大地提高数据分析的效率和准确性。
在使用 Tidyverse
的过程中,我们会经常用到以下几个工具:
-
ggplot2:用于数据可视化,可以绘制各种类型的图表,如散点图、柱状图、折线图等。 -
dplyr:数据整理和转换工具,使用 pipe(%>%)操作符来实现数据的转换和筛选。 -
tidyr:用于数据整理,可以将数据从宽型转换成长型,或将多个变量合并为一个变量。 -
readr:用于读取常见的数据格式,如 CSV、TXT 等。 -
stringr:用于字符串处理,可以进行字符串匹配、提取、替换等操作。 -
tibble:用于创建数据框。
本文将介绍R语言tidyverse
包(包括ggplot2
、dplyr
和tidyr
等),详细讲解这些包的使用方法。我们还将介绍什么是数据可视化、数据整理以及数据转换,这些知识都是数据分析过程中非常重要的基础。在本文中,您将学习到使用R语言进行数据分析的关键技能,例如使用ggplot2
绘制令人惊叹的图表,使用dplyr
和tidyr
包进行数据整理和转换,以及实用技巧,例如如何优雅地操作数据。通过本文的指导,您可以更加高效地进行数据分析,并将这些分析结果以更清晰、优美的图表呈现出来。
二、数据整理与转换
2.1 数据集
-
加载数据集
data(mtcars)
head(mtcars)
-
数据集展示
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
2.2 dplyr
的功能及其用法
dplyr
是一个强大的 R 库,用于数据的整理和转换,它具有简单易用的语法和高效的设计,通常使用 %>%
运算符来组合多种操作。
dplyr 提供一些基本操作,包括:
-
选择数据列(select) -
重命名数据列(rename) -
过滤观测值(filter) -
排序(arrange) -
添加新变量(mutate) -
分组汇总(summarize) -
连接数据集(join)等。
下面是这些操作的详细示例:
2.1.1 选择数据列(select
)
挑选出mtcars数据集中部分数据,比如mpg, cyl 和 disp
library(dplyr)
select_data <- mtcars %>% select(mpg, cyl, disp)
head(select_data)
结果展示:
mpg cyl disp
Mazda RX4 21.0 6 160
Mazda RX4 Wag 21.0 6 160
Datsun 710 22.8 4 108
Hornet 4 Drive 21.4 6 258
Hornet Sportabout 18.7 8 360
Valiant 18.1 6 225
2.1.2 重命名数据列(rename
)
这里将在select_data数据集中重命名mpg为miles_per_gallon
select_data_rename <- select_data %>% rename(miles_per_gallon = mpg)
head(select_data_rename)
结果展示:
miles_per_gallon cyl disp
Mazda RX4 21.0 6 160
Mazda RX4 Wag 21.0 6 160
Datsun 710 22.8 4 108
Hornet 4 Drive 21.4 6 258
Hornet Sportabout 18.7 8 360
Valiant 18.1 6 225
从结果可以看出mpg已被修改为miles_per_gallon
2.1.3 过滤观测值(filter
)
这里我们将过滤出miles_per_gallon大于20的
select_data_rename_flter <- select_data_rename %>% filter(miles_per_gallon >= 20)
head(select_data_rename_flter)
结果展示:
miles_per_gallon cyl disp
Mazda RX4 21.0 6 160.0
Mazda RX4 Wag 21.0 6 160.0
Datsun 710 22.8 4 108.0
Hornet 4 Drive 21.4 6 258.0
Merc 240D 24.4 4 146.7
Merc 230 22.8 4 140.8
2.1.4 排序(arrange
)
这里我们将对miles_per_gallon进行降序排列
select_data_rename_flter_order <- select_data_rename_flter %>% arrange(desc(miles_per_gallon))
head(select_data_rename_flter_order)
结果展示:
miles_per_gallon cyl disp
Toyota Corolla 33.9 4 71.1
Fiat 128 32.4 4 78.7
Honda Civic 30.4 4 75.7
Lotus Europa 30.4 4 95.1
Fiat X1-9 27.3 4 79.0
Porsche 914-2 26.0 4 120.3
从结果可以看出数据按照miles_per_gallon降序排列
2.1.5 添加新变量(mutate
)
select_data_add <- select_data %>% mutate(l_per_100km = 235.21/mpg*100)
head(select_data_add)
结果展示:
mpg cyl disp l_per_100km
Mazda RX4 21.0 6 160 1120.048
Mazda RX4 Wag 21.0 6 160 1120.048
Datsun 710 22.8 4 108 1031.623
Hornet 4 Drive 21.4 6 258 1099.112
Hornet Sportabout 18.7 8 360 1257.807
Valiant 18.1 6 225 1299.503
2.1.6 分组汇总(summarize)
按照cyl分组,然后平均值
select_data_add_group <- select_data_add %>% group_by(cyl) %>% summarize(mean_mpg = mean(mpg))
head(select_data_add_group)
结果展示:
# A tibble: 3 × 2
cyl mean_mpg
<dbl> <dbl>
1 4 26.7
2 6 19.7
3 8 15.1
2.1.7 连接数据集(join
)
新建两个数据集,通过连接键id进行关联,然后将两个数据集整合在一起
df1 <- data.frame(id = c(1,2,3), var1 = c("a","b","c"))
df2 <- data.frame(id = c(1,2,4), var2 = c("A","B","D"))
inner_join(df1, df2, by="id")
结果展示:
id var1 var2
1 1 a A
2 2 b B
从结果可以看出数据已经拼接在一起了。
2.3 tidyr
的功能及其用法
tidyr
是一个 R 库,用于数据整理和转换,它强调数据的长型与宽型转换,经常与 dplyr
结合使用,提供了许多有用的函数,如 gather
、spread
、separate
和 unite
等。
-
gather:将数据从宽型转换成长型。 -
spread:将数据从长型转换成宽型。 -
separate:将一个变量拆分成多个变量。 -
unite:将多个变量合并为一个变量。
下面是这些转换方法的详细示例:
2.3.1 创建演示数据集
df <- data.frame(country = c("USA", "Canada", "Mexico"),
`2000` = c(5, 2, 10),
`2001` = c(7, 3, 9))
结果展示:
country X2000 X2001
1 USA 5 7
2 Canada 2 3
3 Mexico 10 9
2.3.2 宽类型转长类型(gather
)
该函数将数据从宽格式转换为长格式。宽格式一般是指包含多列数据的格式,而长格式则是指只包含两列数据(变量列和值列)的格式。
使用方法:
gather(df, key = "variable", value = "value", cols = c("col1", "col2", ...))
示例:
library(tidyr)
library(dplyr)
# 将宽格式数据变为长格式数据
df_long <- df %>%
gather(key = "year", value = "value",-c("country"))
df_long
结果展示:
country year value
1 USA X2000 5
2 Canada X2000 2
3 Mexico X2000 10
4 USA X2001 7
5 Canada X2001 3
6 Mexico X2001 9
2.3.2 长类型转宽类型(spread
)
该函数将数据从长格式转换为宽格式。它通常用于将多个值列转换为单个宽型数据框中的列。
使用方法:
spread(df, key = "variable_name", value = "value")
示例:
df_wide <- df_long %>%
spread(key = "year", value = "value")
df_wide
结果展示:
country X2000 X2001
1 Canada 2 3
2 Mexico 10 9
3 USA 5 7
2.3.3 拆分变量(separate
)
该函数将一个变量拆分成多个变量。
使用方法:
separate(data, col, into, sep, remove = TRUE, convert = FALSE)
示例:
df <- data.frame(full_name = c("Steve Smith", "Bob Johnson", "Alice Chen"),
age = c(25, 30, 27),
salary = c("$100,000", "$80,000", "$120,000"))
df
df_separate <- df %>%
separate(full_name, c("first_name", "last_name"), sep = " ")
df_separate
结果展示:
# df
full_name age salary
1 Steve Smith 25 $100,000
2 Bob Johnson 30 $80,000
3 Alice Chen 27 $120,000
# df_separate
first_name last_name age salary
1 Steve Smith 25 $100,000
2 Bob Johnson 30 $80,000
3 Alice Chen 27 $120,000
在上面的示例中,我们使用 separate() 函数将 full_name 列拆分成 first_name 和 last_name 两列,并使用空格作为分隔符。
2.3.4 合并变量(unite
)
该函数将多个变量合并为一个变量。
使用方法:
unite(data, col, ..., sep = "_", remove = TRUE)
示例:
df_unit <- df_separate %>%
unite(full_name, c("first_name", "last_name"), sep = " ")
df_unit
结果展示:
full_name age salary
1 Steve Smith 25 $100,000
2 Bob Johnson 30 $80,000
3 Alice Chen 27 $120,000
三、数据分析实战
在这部分中,我们将演示如何使用R语言中的ggplot2
、dplyr
和tidyr
库进行数据分析。我们将使用一个真实的数据集,并进行数据导入、清洗、转换、分析和可视化等多个任务。通过本部分的演示,读者可以更好地理解ggplot2
、dplyr
和tidyr
的相关知识,并在相似的数据分析任务中应用它们。
我们的任务是分析一份R语言自带的花的数据集。数据集包含了:
-
Sepal.Length:萼片长度,以厘米为单位 -
Sepal.Width:萼片宽度,以厘米为单位 -
Petal.Length:花瓣长度,以厘米为单位 -
Petal.Width:花瓣宽度,以厘米为单位 -
Species:鸢尾花的品种,包括三个类别:setosa、versicolor和virginica
我们将尝试回答以下问题:
-
不同品种鸢尾花的花瓣长度和宽度是否存在差异? -
鸢尾花的大小是否与种类有关?
3.1 加载数据集
#加载iris数据集
data(iris)
#查看前几行数据
head(iris)
结果展示:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
3.2 花瓣长度和宽度是否存在差异?
-
首先,我们用gather()函数将数据从宽格式变为长格式,以便更好地进行可视化
#使用gather函数将数据从宽格式变为长格式
iris_long <- iris %>%
gather(key = "measurement", value = "value", Sepal.Length:Petal.Width)
iris_long
结果展示:
Species measurement value
1 setosa Sepal.Length 5.1
2 setosa Sepal.Length 4.9
3 setosa Sepal.Length 4.7
4 setosa Sepal.Length 4.6
5 setosa Sepal.Length 5.0
6 setosa Sepal.Length 5.4
-
然后,我们使用facet_grid()函数将不同种类的鸢尾花绘制在不同的子图中,更好地比较不同种类之间的差异。
#使用facet_grid()函数将不同品种鸢尾花绘制在不同的子图中
ggplot(iris_long, aes(x = measurement, y = value, fill = Species)) +
geom_boxplot() +
facet_grid(. ~ Species) +
theme_bw() +
labs(title = "不同品种鸢尾花的花瓣长度和宽度") +
xlab("Measurement") +
ylab("Value")
我们可以看到,不同品种鸢尾花的花瓣长度和宽度确实存在差异。鸢尾花“setosa”的花瓣相对较短而宽,而鸢尾花“versicolor”和“virginica”的花瓣相对较长但宽度较窄。
3.3 花的大小是否与种类有关?
接下来,我们可以使用dplyr
库计算每朵鸢尾花的大小,并使用ggplot2
可视化不同品种鸢尾花的大小分布情况。
#计算每朵鸢尾花的大小
iris <- iris %>%
mutate(size = Petal.Length * Petal.Width)
结果展示:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species size
1 5.1 3.5 1.4 0.2 setosa 0.28
2 4.9 3.0 1.4 0.2 setosa 0.28
3 4.7 3.2 1.3 0.2 setosa 0.26
4 4.6 3.1 1.5 0.2 setosa 0.30
5 5.0 3.6 1.4 0.2 setosa 0.28
6 5.4 3.9 1.7 0.4 setosa 0.68
绘图:
#绘制不同品种鸢尾花的大小分布情况
ggplot(iris, aes(x = Species, y = size, fill = Species)) +
geom_boxplot() +
theme_bw() +
labs(title = "不同品种鸢尾花的大小") +
xlab("Species") +
ylab("Size")
我们可以看到,不同品种鸢尾花的大小分布情况也存在差异。鸢尾花“virginica”的大小分布最大,而鸢尾花“setosa”的大小分布最小。
四、实用技巧
4.1 读写数据文件
在R中读取和写入数据文件是数据分析任务中非常常见的操作。可以使用base R中的read.table()
或write.table()
函数,也可以使用readr包中的read_csv()
或write_csv()
等函数。
4.2 函数编写
在数据分析任务中,通常需要多次进行相同的数据转换操作。为了简化代码和提高效率,可以编写自己的函数来执行这些重复的任务。在R中,函数的编写非常简单,可以使用function()和return()语句创建自己的函数并执行特定操作。
4.3 R语言便捷快捷的代码技巧
-
使用管道符( %>%
):该符号可以大大减少代码长度和提高代码可读性。它允许你将一系列函数链接在一起,并将中间结果传递给下一个函数。 -
使用匿名函数:在某些情况下,使用匿名函数可以减少代码量。通过使用(function(x) x^2)(5)这样的语法,可以直接对5进行平方运算,而不必定义一个具名函数。 -
使用向量化操作:R中很多函数都是向量化的,这意味着它们可以同时处理整个向量。在处理数据分析任务中的大数据时,这是非常有用的。