r - 平行坐标图中每个级别的单独 y 轴
问题描述
我正在尝试生成一个平行坐标图,其中每个变量都有自己的轴。例如:
到目前为止,我已经使用ggparcoord()
了 package中的函数GGally
。但是,据我所知,它不允许每个变量都像上面那样有自己的轴。
有谁知道如何使用R
,最好使用ggplot2
?提前致谢。
解决方案
我不知道有任何软件包可以做到这一点,但是在 ggplot 中自己绘制轴并不难。
假设我们有一个与示例图中显示的数据集相似的数据集:
library(ggplot2)
library(dplyr)
cars <- mtcars %>%
select(c(2:4, 6:7, 1)) %>%
tibble::rownames_to_column("model") %>%
as_tibble()
cars
#> # A tibble: 32 x 7
#> model cyl disp hp wt qsec mpg
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Mazda RX4 6 160 110 2.62 16.5 21
#> 2 Mazda RX4 Wag 6 160 110 2.88 17.0 21
#> 3 Datsun 710 4 108 93 2.32 18.6 22.8
#> 4 Hornet 4 Drive 6 258 110 3.22 19.4 21.4
#> 5 Hornet Sportabout 8 360 175 3.44 17.0 18.7
#> 6 Valiant 6 225 105 3.46 20.2 18.1
#> 7 Duster 360 8 360 245 3.57 15.8 14.3
#> 8 Merc 240D 4 147. 62 3.19 20 24.4
#> 9 Merc 230 4 141. 95 3.15 22.9 22.8
#> 10 Merc 280 6 168. 123 3.44 18.3 19.2
#> # ... with 22 more rows
我们可以使用一些简单的算术计算轴中断(并设置刻度线的坐标):
axis_df <- stack(cars[-1]) %>%
group_by(ind) %>%
summarize(breaks = pretty(values, n = 10),
yval = (breaks - min(breaks))/(max(values) - min(values))) %>%
mutate(xmin = as.numeric(ind) - 0.05,
xmax = as.numeric(ind),
x_text = as.numeric(ind) - 0.2)
我们的实际轴线的坐标如下:
axis_line_df <- axis_df %>%
group_by(ind) %>%
summarize(min = min(yval), max = max(yval))
现在我们需要对原始数据进行整形和标准化:
lines_df <- cars[-1] %>%
mutate(across(everything(), function(x) (x - min(x))/(max(x) - min(x)))) %>%
stack() %>%
mutate(row = rep(cars$model, ncol(cars) - 1))
最后,绘图代码将类似于:
ggplot(lines_df, aes(ind, values, group = row)) +
geom_line(color = "orange", alpha = 0.5) +
geom_segment(data = axis_line_df, aes(x = ind, xend = ind, y = min, yend = max),
inherit.aes = FALSE) +
geom_segment(data = axis_df, aes(x = xmin, xend = xmax, y = yval, yend = yval),
inherit.aes = FALSE) +
geom_text(data = axis_df, aes(x = x_text, y = yval, label = breaks),
inherit.aes = FALSE) +
geom_text(data = axis_line_df, aes(x = ind, y = 1.2, label = ind),
size = 6, inherit.aes = FALSE, check_overlap = TRUE, hjust = 1) +
theme_void() +
theme(plot.margin = margin(50, 20, 50, 20))
由reprex 包于 2021-10-24 创建 (v2.0.0 )
推荐阅读
- sql - 如何通过 Vertica SQL 中的多个列及其类别获取主键计数?
- sql - 按具有起点和终点 SQL Server 的动态间隔分组
- c# - 编辑完成后 C# DataGridView 数据移动到下一个单元格
- c# - 使用 C# 从 MS Graph API 中的消息中获取 EventMessage
- sql - SQL - 计算每年相同日期之间的日期
- regex - Angular中的货币正则表达式
- ios - 如何在 XCode 中禁用记录动态加载器事件(dyld)?
- django - 如何在 Django 序列化程序中将深度设置为关系深度?
- sql-server - SQL Server:使用 UNIX 时间戳获取前一天的结果
- javascript - 如何设置加载页面以在网站在后台加载时进行预览