ggplot2与数据可视化技巧解析

table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}

34、ggplot的前两个参数是数据(data)和映射(mapping),所有图层函数的前两个参数是映射(mapping)和数据(data)。为什么参数顺序不同?(提示:想想你最常设置的是什么。)

推测是因为使用

ggplot

时通常先确定数据,再考虑映射;而使用图层函数时,可能更关注映射如何应用于特定数据,所以顺序不同。

35、以下代码使用 dplyr 为每类汽车生成一些汇总统计信息。library(dplyr); class <- mpg %>% group_by(class) %>% summarise(n = n(), hwy = mean(hwy))。使用这些数据绘制一个柱状图,x 轴为汽车类别(class),y 轴为高速公路平均油耗(hwy),并在柱子上方显示每类汽车的数量(n),y 轴范围设置为 0 到 40。

可能需要使用

ggplot2

绘图,示例代码如下:


library(ggplot2)
library(dplyr)

class <- mpg %>% 
  group_by(class) %>% 
  summarise(n = n(), hwy = mean(hwy))

ggplot(class, aes(x = class, y = hwy)) + 
  geom_col() + 
  geom_text(aes(label = paste0('n = ', n)), vjust = -0.5) + 
  scale_y_continuous(limits = c(0, 40))

此代码仅供参考,实际可能需根据图形具体样式调整。

36、以下代码的作用是什么?它能正常运行吗?是否合理?为什么?ggplot(mpg) + geom_point(aes(class, cty)) + geom_boxplot(aes(trans, hwy))

这段代码尝试在同一个图中绘制散点图和箱线图。散点图以

class

为 x 轴,

cty

为 y 轴;箱线图以

trans

为 x 轴,

hwy

为 y 轴。代码能运行,但不太合理,因为 x 轴变量不同,图形叠加会使可视化混乱,难以解读数据关系。

37、掌握一个不熟悉的几何对象(geom)的最佳方法是什么?列出三个有助于入门的资源。

最佳方法可以是:

阅读官方文档

参考在线教程

实践练习

三个入门资源可以是:

官方文档网站

专业的数据可视化博客

相关的书籍

38、对于下面的每个图,确定用于绘制它的几何对象。

point

图使用

geom_point()

text

图使用

geom_text()

bar

图使用

geom_bar(stat = "identity")

raster

图使用

geom_tile()

line

图使用

geom_line()

area

图使用

geom_area()

path

图使用

geom_path()

polygon

图使用

geom_polygon()

39、使用 geom_count() 创建一个图表,展示 mpg 数据集中每种 drv 和 trans 组合下汽车的比例。

使用以下基本代码框架解决问题:


ggplot(mpg, aes(drv, trans)) + 
  geom_count()

后续还需根据比例计算需求进一步处理数据和调整图表。

40、许多位置调整只能与少数几何对象(geom)一起使用。例如,不能堆叠箱线图或误差线。为什么不行呢?一个几何对象必须具备哪些属性才能进行堆叠?必须具备哪些属性才能进行并列放置?

一般来说,不能堆叠箱线图或误差线是因为堆叠会破坏其展示数据分布和统计信息的意义。一个几何对象要可堆叠,需有明确的底部边界且堆叠后能清晰展示各部分数据;要可并列放置,需有可分组的属性且并列后各部分数据能清晰区分。

41、为什么你可能会使用 geom_jitter() 而不是 geom_count()?这两种技术各有什么优缺点?

一般来说,

geom_jitter()

用于随机抖动重叠点,能减轻数据重叠问题,在数据有一定离散性时结合透明度使用效果好,可保留原始数据点位置信息,但可能引入噪声;

geom_count()

用于统计不同位置的点数,能直观展示数据聚集程度,但会丢失原始数据点位置信息。

42、列出可以提供给breaks参数的三种不同类型的对象。breaks和labels有什么区别?

参数

breaks

可接受的三类对象

可提供给

breaks

参数的三种不同类型的对象如下:


数值向量


可直接指定刻度位置。


函数


例如,函数应接受一个包含两个元素的数值向量(表示范围),并返回一个数值向量作为刻度位置。


字符串


例如

'pretty'

等预定义的方法字符串。

相关参数说明


breaks



用于指定刻度的位置,是一个数值向量。


labels



用于指定刻度的标签,是一个与

breaks

长度相同的字符向量。

43、你能重新创建这个绘图的代码吗?

下面是给定的【文本内容】:

示例绘图代码为

ggplot(mpg, aes(displ, hwy)) + geom_point(aes(colour = class)) + geom_smooth(method = "lm", se = FALSE) + theme(legend.position = "none")

,不清楚你具体指哪个绘图,若需创建其他绘图请明确描述绘图细节。

44、如果在同一个图中添加两个xlim()调用会发生什么?为什么?

在同一个图中添加两个

xlim()

调用时,第二个

xlim()

调用会覆盖第一个

xlim()

调用所设置的 x 轴范围。

原因是

xlim()

函数的作用是设置当前图形的 x 轴显示范围,每次调用该函数时,它会更新当前图形对象中关于 x 轴范围的设置。当第二次调用

xlim()

时,它会用新指定的范围替换掉之前已经设置好的 x 轴范围,从而使得最终显示的图形 x 轴范围是第二次调用

xlim()

所指定的范围。

45、scale_x_continuous(limits = c(NA, NA)) 有什么作用?


scale_x_continuous

里用

limits = c(NA, NA)

是不改变连续型 x 轴的默认范围,让其依据数据自动确定范围。

46、钻石:比较每种颜色下价格与克拉数之间的关系。是什么让这些组之间难以比较?分组和分面哪种方式更好?如果你使用分面,添加什么注释能让你更轻松地看出各面板之间的差异?

一般来说,难以比较的原因可能是不同颜色的钻石在克拉数和价格的分布上有重叠、数据量差异大等;

分组和分面哪种更好取决于数据特点和分析目的:



分组

:适合观察整体趋势



分面

:适合对比组间差异

使用分面时可添加以下注释来便于看出差异:

– 均值线

– 中位数线

– 参考线

– 标签等

47、为什么facet_wrap()通常比facet_grid()更有用?


`facet_wrap()` 适合处理单个有多个水平的变量,能以更节省空间的方式排列图形,将一维图形带包装成二维,可能因此更常用。

48、重新创建绘图。已知有一个名为 mpg2 的数据集,按该数据集中的类别对其进行分面,并在绘图上叠加一条拟合整个数据集的平滑曲线。

使用

ggplot2

包,先按类别对

mpg2

进行分面,再拟合整个数据集的平滑曲线并叠加。示例代码如下:


ggplot(mpg2, aes(x = displ, y = hwy)) + 
  geom_point() + 
  geom_smooth(data = mpg2, method = 'loess') + 
  facet_wrap(~class)

49、尝试 ggthemes 中的所有主题。你最喜欢哪一个?

可按实际尝试情况选择

50、查看你最喜欢的科学期刊中的图表。它们最接近哪种主题?主要区别是什么?

一般来说,科学期刊的图表可能接近

theme_minimal

(简约主题),因其无背景注释,简洁专业;也可能接近

theme_bw

(黑白主题),白色背景搭配细灰网格线,清晰易读。主要区别需依据期刊图表的具体样式,如字体、线条粗细、背景颜色等与对应主题默认设置比较得出。

51、创建一个尽可能难看的图表!(由田纳西大学诺克斯维尔分校的安德鲁·D·斯汀提供)

可通过不合理配色(如高饱和度红绿搭配)、过多元素堆叠、不恰当的图形样式(如用折线图展示分类数据)等方式创建难看的图表。

52、从https://github.com/rstudio/EDAWR安装EDAWR包,并整理who数据集。

若要完成此任务,可先使用

devtools::install_github('rstudio/EDAWR')

安装EDAWR包,然后使用数据整理相关函数(如

gather


separate

等)对

who

数据集进行整理,但具体代码需结合

who

数据集的实际情况编写。

53、运行 tidyr 包中包含的演示

可在 R 语言环境中输入

demo(package = "tidyr")

来运行

tidyr

包中的演示。

54、通过以下条件练习你的筛选技能:找出所有 x 和 y 尺寸相等的钻石;深度在 55 到 70 之间的钻石;克拉数小于克拉数中位数的钻石;每克拉成本超过 10000 美元的钻石;品质为好或更好的钻石。

可使用如下筛选条件:

x 和 y 尺寸相等:

x == y

深度在 55 到 70 之间:

depth >= 55 & depth < 70

克拉数小于克拉数中位数:

carat < median(carat)

每克拉成本超过 10000 美元:

price / carat > 10000

品质为好或更好:

cut %in% c("Good", "Very Good", "Premium", "Ideal")

55、安装 ggplot2movies 包,查看预算缺失的电影。它们与有预算的电影有何不同?(提示:尝试使用频率多边形并设置 colour = is.na(budget))

可安装

ggplot2movies

包,绘制频率多边形(

colour = is.na(budget)

)来对比预算缺失和有预算的电影差异。

56、NA & FALSE 和 NA | TRUE 的结果是什么?为什么?为什么 NA * 0 不等于零?什么数乘以零不等于 0?你认为 NA ^ 0 等于什么?为什么?


NA & FALSE 结果为 FALSE,因为与运算中只要有一个为 FALSE 结果就是 FALSE;  
NA | TRUE 结果为 TRUE,因为或运算中有一个为 TRUE 结果就是 TRUE。  

NA * 0 不等于零是因为 NA 代表未知值,未知值与 0 相乘结果仍未知。任何实数乘以零都等于 0,在常规数学概念里不存在乘以零不等于 0 的数。  

NA ^ 0 通常认为等于 1,因为任何非零数的 0 次方都等于 1,但由于 NA 未知,严格来说结果还是 NA。

57、深度变量是钻石的宽度(x 和 y 的平均值)除以其高度(z),再乘以 100 并四舍五入到最接近的整数。已知钻石的宽度 x、宽度 y 和高度 z 的值以及数据集中现有的深度变量数据,自己计算深度并将其与现有的深度变量进行比较。用图表总结你的发现。

首先根据公式 $ frac{(x + y)}{2 imes z} imes 100 $ 计算深度并四舍五入,然后将计算结果与数据集中现有的深度变量对比,最后用合适的图表(如散点图)展示两者差异。

58、比较x > y和x < y的钻石的对称性分布。

可通过以下步骤解决:

对钻石数据按

x > y


x < y

的条件进行分组;

计算每组中钻石对称性的相关统计量(如均值、中位数、标准差等);

使用合适的可视化方法(如箱线图、直方图等)展示两组的对称性分布并进行比较。

59、对于

ggplot2movies::movies

数据中的每一年,确定预算缺失的电影所占的百分比,并将结果可视化。

可使用R语言按以下步骤操作:首先加载数据,按年份分组,计算每年预算缺失电影的百分比,最后使用

ggplot2

进行可视化。

示例代码如下:


library(ggplot2)
library(ggplot2movies)

# 计算每年预算缺失电影的百分比
movies <- ggplot2movies::movies
missing_budget_percentage <- movies %>%
  group_by(year) %>%
  summarise(percent_missing = mean(is.na(budget)) * 100)

# 可视化结果
ggplot(missing_budget_percentage, aes(x = year, y = percent_missing)) +
  geom_line() +
  labs(x = "年份", y = "预算缺失电影的百分比", title = "每年预算缺失电影的百分比")

60、电影的平均时长如何随时间变化?用一个包含不确定性展示的图表来呈现你的答案。


从 `ggplot2movies::movies` 数据中提取电影时长和年份信息,按年份分组计算平均时长及不确定性指标(如标准差),然后使用 `ggplot2` 绘图,可结合 `geom_smooth(stat = "identity")` 等展示不确定性。示例代码框架如下:

```r
library(ggplot2)
library(ggplot2movies)

movies <- ggplot2movies::movies

movie_summary <- aggregate(length ~ year, data = movies, FUN = function(x) c(mean = mean(x), sd = sd(x)))

movie_summary <- as.data.frame(movie_summary)

colnames(movie_summary) <- c("year", "mean_length", "sd_length")

ggplot(movie_summary, aes(x = year, y = mean_length, ymin = mean_length - sd_length, ymax = mean_length + sd_length)) +
  geom_point() +
  geom_smooth(stat = "identity")

61、对于钻石质量的每种组合(例如切工、颜色和净度),统计钻石的数量、平均价格和平均尺寸。对结果进行可视化。

一般步骤为:

使用数据处理工具(如R语言中的

dplyr

包)按切工、颜色和净度分组,统计每组钻石数量、计算平均价格和平均尺寸;

然后使用可视化工具(如R语言中的

ggplot2

包)选择合适图表(如柱状图、散点图等)进行可视化展示。

62、在棒球示例中,随着击球次数的增加,击球率似乎也在增加。为什么?

当击球次数增加时,球员有更多机会适应比赛、积累经验,技术发挥更稳定,且能减少因偶然因素导致的低击球率情况,从而使击球率更接近真实水平,看起来击球率会增加。

63、能否创建一个图表,同时展示颜色、切工和净度对相对价格的影响?如果一张图表无法展示过多信息,思考如何创建一系列图表来传达相同的信息。

可考虑使用分面图,按颜色、切工或净度中的一个变量进行分面,在每个分面中展示另外两个变量与相对价格的关系;

也可创建多个图表,分别展示颜色与相对价格、切工与相对价格、净度与相对价格的关系。

64、最终的图表在整体趋势中显示出大量短期噪声。如何进一步平滑处理以关注长期变化?

可使用时间序列平滑方法,如:

移动平均法

指数平滑法

或使用

geom_smooth()

函数并调整参数,如设置合适的

span

值。

65、此数据集中并非所有城市都有完整的时间序列。运用你的 dplyr 技能,计算每个城市缺失了多少数据,并通过可视化展示结果。


使用 `dplyr` 对数据按城市分组,统计每个城市应有的数据量和实际的数据量,二者差值即为缺失数据量,然后用合适的可视化方法(如柱状图)展示每个城市的缺失数据量。

66、使用dplyr重复stat_summary()的计算,以便你可以“手动”绘制数据。

一般而言,要使用

dplyr

重复

stat_summary()

的计算,可按以下步骤操作:

使用

group_by()

对数据分组;


summarise()

计算统计量;


ggplot()


geom_()

函数手动绘图。

例如,若要计算不同

trans

组的

cty

均值,代码如下:


library(dplyr)
library(ggplot2)

summary_data <- mpg %>% 
  group_by(trans) %>% 
  summarise(mean_cty = mean(cty))

ggplot(summary_data, aes(trans, mean_cty)) + 
  geom_point()

67、创建一个分面图,展示所有城市的季节性模式。按城市的R²值对分面进行排序。

要实现此需求,可先计算各城市的 R² 值,根据 R² 值对城市排序,然后使用

ggplot2


facet_wrap


facet_grid

函数创建分面图并按排序后的城市顺序展示。示例代码如下(假设数据框为

extreme

,包含

month


sales


year


city

等列):


# 假设已有计算R²的函数get_R2,这里简单示意
library(dplyr)

extreme <- extreme %>%
  group_by(city) %>%
  mutate(R2 = get_R2()) %>%
  ungroup()

# 按R²排序城市
city_order <- extreme %>%
  distinct(city, R2) %>%
  arrange(R2) %>%
  pull(city)

extreme$city <- factor(extreme$city, levels = city_order)

# 创建分面图
ggplot(extreme, aes(month, log(sales))) +
  geom_line(aes(group = year)) +
  facet_wrap(~ city)

以上代码仅为示例,实际中需要根据数据和具体需求调整。

68、提取出季节性影响最强和最弱的三个城市,并绘制它们的系数图。

可按以下步骤操作:

先使用代码

r
coef_sum <- months %>% group_by(city) %>% summarise(max = max(estimate))


计算每个城市的最大估计值。

然后按最大估计值排序,提取出最大和最小的三个城市。

最后绘制这六个城市的系数图(未给出具体绘图代码)。

69、当你的结果与先入为主的观念相符时,你应该格外谨慎。你如何证实或反驳关于强烈季节性模式成因的假设?

可考虑收集更多相关数据,分析不同因素与季节性模式的关联;

进行对比实验,控制其他变量,观察特定因素变化对季节性模式的影响;

运用统计检验方法验证假设的显著性等。

70、将钻石数据按切工(cut)、净度(clarity)和颜色(colour)分组。拟合一个线性模型 log(price) ~ log(carat)。截距说明了什么?斜率说明了什么?截距和斜率在各分组间如何变化?

在线性模型

log(price) ~ log(carat)

中:


截距

表示当

log(carat)

为 0 时,

log(price)

的预测值;


斜率

表示

log(carat)

每变化一个单位时,

log(price)

的平均变化量。

要观察截距和斜率在各分组间的变化,可以在按要求分组后分别拟合模型,然后使用绘图工具(如

ggplot2

)绘制各分组对应的拟合直线,以直观展示其差异。

71、为每个城市创建 log(sales) 的时间序列。突出显示标准化残差大于 2 的点。

可使用 R 语言结合相关数据,先创建

log(sales)

时间序列,再筛选出标准化残差大于 2 的点进行突出显示,代码示例:


ggplot(txhousing, aes(date, log(sales))) + 
  geom_line(aes(group = city)) + 
  geom_point(data = subset(txhousing, abs(.std.resid) > 2), 
             aes(date, log(sales)), 
             color = 'red')

需根据实际数据调整。

72、创建一个代表有100个区间的粉色直方图的对象。

可使用 R 语言的

ggplot2

包,示例代码如下:


library(ggplot2)
p <- ggplot(data, aes(x = variable)) + 
  geom_histogram(bins = 100, fill = "pink")

其中

data

是数据集,

variable

是要绘制直方图的变量。

73、扩展 borders() 函数,使其还能向绘图中添加 coord_quickmap()。

可定义一个新函数,在其中调用

borders()

函数并添加

coord_quickmap()

,示例代码如下:


new_borders <- function(database = "world", regions = ".", fill = NA, colour = "grey50", ...) {
  p <- borders(database = database, regions = regions, fill = fill, colour = colour, ...)
  p + coord_quickmap()
}

74、查看你自己的代码。你一直使用哪些几何图形或比例尺的组合?你如何将这种模式提取为一个可重复使用的函数?

可通过识别代码中反复出现的几何图形或比例尺组合,将其封装在一个函数里,函数接收必要的数据和参数,在函数内部编写绘图代码,最后返回完整的绘图对象,实现模式提取为可重复使用的函数。

© 版权声明

相关文章

暂无评论

none
暂无评论...