R-ggplot2-今天来说说坐标轴在绘图过程中出现乱序的问题

目录

  • 0.问题导入
  • 1.随机生成示例数据
  • 2.默认数据可视化(图1)
  • 3.字母加数字内置顺序排列错误排除
  • 4.字母+数字内置顺序排列错误排除后结果可视化(图2)
  • 5.字符串排列问题示例数据生成
  • 6.R中字符串顺序排列示例(图3)
  • 7.自定义横轴顺序
  • 8.自定义横轴顺序后结果可视化(图4)
  • 9.本篇总结
  • 10.本文所用到package(若没有需要通过install.packages 进行安装)
  • 11.致谢

0. 问题导入

有时候,我们在绘图过程中,横轴/纵轴往往不是连续变量,如时间,指标值等,就会存在R内置排序的问题。
对于字母与数字组合,若位数大于2,如 S1, S2, S3 ... S10, S11, S12...等这样的元素,R会优先按照个位大小进行优先排序,就会导致S1,S10,S11,S12,S2...,S9这样的乱序结果(如图1)。而我们有时候会需要进行顺序的样本比较,那么这样的问题如何解决呢?本篇给出解决方案~

图1 字母+数字乱序示例

1. 随机生成示例数据

x = paste0('S',1:20)
y = runif(20,-5,5)

pl_df = data.frame(x = x,y = y)

neg_index = which(pl_df$y < 0)
pl_df$fill = 'Positive Zone'
pl_df$fill[neg_index] = 'Negative Zone'

colnames(pl_df) = c('Sample','Value','Type')

数据结构一览:

  • Sample 代表样本编号,在地里应用中可以是多个栅格,或是多个样点;
  • Value表示样本对应的指标值;
  • Type表示各样本点指标值是否小于0的判断结果。
head(pl_df)
  Sample     Value          Type
1     S1  3.596238 Positive Zone
2     S2  3.188980 Positive Zone
3     S3 -1.661844 Negative Zone
4     S4  4.682527 Positive Zone
5     S5 -3.507134 Negative Zone
6     S6  4.383677 Positive Zone

2. 默认数据可视化(图1)

fontsize  = 12

p = ggplot()+
  geom_bar(data = pl_df, aes(x = Sample, y = Value, fill = Type),position = 'dodge',stat = 'identity')+
  theme_bw()+
  theme(
    axis.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    axis.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.position = 'bottom',
    legend.direction = 'horizontal',
    legend.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5)
  )+
  xlab('Sample Index')+
  ylab('Testing Value')

#dir.create('plot')
png('plot/plot1.png',
    height = 15, 
    width = 25,
    units = 'cm',
    res = 800)
print(p)
dev.off()

3. 字母加数字内置顺序排列错误排除

对,就是一行,而往往为了解决这个问题,我们可能需要上网搜很多帖子,花费最少1-2个小时解决这个问题。本文直接为大家提供方便,直接给出解决方案。

pl_df$Sample = factor(pl_df$Sample,
                      levels = x)

给完解决方案,我们来说说后面的原理。由于字母加数字组合之后,R系统会从字符串第一位开始比较,直到最后一位。比较规则以a-z, A-z, 1-9来进行先后排序,而不会根据个位+十位组合后的数值大小进行比较。这也是出现乱序的原因。

这里提出的解决方案是将如下Sample元素的Level 按照我们的需求进行自定义。
注意:如下展示的是更新前的pl_df$Sample 的Levels.

unique(pl_df$Sample)
 [1] S1  S2  S3  S4  S5  S6  S7  S8  S9  S10 S11 S12 S13 S14 S15 S16 S17 S18 S19 S20
Levels: S1 S10 S11 S12 S13 S14 S15 S16 S17 S18 S19 S2 S20 S3 S4 S5 S6 S7 S8 S9

并转换为如下 Levels为我们期望的排列顺序(更新后的pl_df$Sample 的Levels)

 pl_df$Sample
 [1] S1  S2  S3  S4  S5  S6  S7  S8  S9  S10 S11 S12 S13 S14 S15 S16 S17 S18 S19 S20
Levels: S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 S16 S17 S18 S19 S20

4. 字母+数字内置顺序排列错误排除后结果可视化(图2)

如图2红框所示,我们解决了R中字母+数字内置顺序排列的错误,按照我们预设的正确顺序进行了排列。

p2 = ggplot()+
  geom_bar(data = pl_df, aes(x = Sample, y = Value, fill = Type),position = 'dodge',stat = 'identity')+
  theme_bw()+
  theme(
    axis.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    axis.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.position = 'bottom',
    legend.direction = 'horizontal',
    legend.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5)
  )+
  xlab('Sample Index')+
  ylab('Testing Value')

#dir.create('plot')
png('plot/plot2.png',
    height = 15, 
    width = 25,
    units = 'cm',
    res = 800)
print(p2)
dev.off()
图2 字母+数字内置顺序排列错误排除后结果可视化

然而,小编写到这的时候又想到了一个问题。有时候,我们需要比较的对象是全字符编码的,如"Beijing", "Shanghai"等的城市名,或是病患A,病患B等。R的绘图系统会默认根据字母a-z/A-Z进行顺序排列。但这真的是我们想要的吗?

比如,我们我们可能需要比较Beijing/Shanghai/AnHui等多个地区的GDP产值。但若根据字符排序,AnHui会排到Beijing前面,而Shanghai则会与Beijing分开。如果我们的研究重点是将Beijing-Shanghai进行横向比较的化,问题该怎么解决呢?本篇同样给出解决方案


5. 字符串排列问题示例数据生成

index = round(runif(20,1,26))
index2 = round(runif(20,1,26))
x2 = paste0(LETTERS[index],letters[index2])

pl_df2 = data.frame(City_initial = x2, GDP = y)
pl_df2$Type = 'Positive Value'
neg_index = which(pl_df2$GDP <0)
pl_df2$Type[neg_index] = 'Negative Value'

数据结构预览:

  City_initial       GDP           Type
1           We  3.596238 Positive Value
2           Kh  3.188980 Positive Value
3           Dd -1.661844 Negative Value
4           Pi  4.682527 Positive Value
5           Xw -3.507134 Negative Value
6           Hm  4.383677 Positive Value

6. R中字符串顺序排列示例(图3)

若不经处理直接按照以下代码绘图,R会根据字符串进行顺序排列,结果如图3。

p3 = ggplot()+
  geom_bar(data = pl_df2, aes(x = City_initial, y = GDP, fill = Type),position = 'dodge',stat = 'identity')+
  theme_bw()+
  theme(
    axis.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    axis.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.position = 'bottom',
    legend.direction = 'horizontal',
    legend.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5)
  )+
  xlab('City Initials')+
  ylab('Testing Value')

#dir.create('plot')
png('plot/plot3.png',
    height = 15, 
    width = 25,
    units = 'cm',
    res = 800)
print(p3)
dev.off()
图3 R中字符串顺序排列示例

7. 自定义横轴顺序

自定义横轴顺序与字母+数字的定义方式原理一样,我们需要进行如下设置:

#转换前City_initial 结构
unique(pl_df2$City_initial)
 [1] We Kh Dd Pi Xw Hm Sf Pn Oc Ux Qm Fi Om Et Ks Wm Eb Ou Hv On
Levels: Dd Eb Et Fi Hm Hv Kh Ks Oc Om On Ou Pi Pn Qm Sf Ux We Wm Xw
#自定义横轴顺序
pl_df2$City_initial = factor(pl_df2$City_initial,
                             levels = x2)
#转换后City_initial 顺序
[1] We Kh Dd Pi Xw Hm Sf Pn Oc Ux Qm Fi Om Et Ks Wm Eb Ou Hv On
Levels: We Kh Dd Pi Xw Hm Sf Pn Oc Ux Qm Fi Om Et Ks Wm Eb Ou Hv On

8. 自定义横轴顺序后结果可视化(图4)

p4 = ggplot()+
  geom_bar(data = pl_df2, aes(x = City_initial, y = GDP, fill = Type),position = 'dodge',stat = 'identity')+
  theme_bw()+
  theme(
    axis.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    axis.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.position = 'bottom',
    legend.direction = 'horizontal',
    legend.text = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5),
    legend.title = element_text(face = 'bold',color = 'black',size = fontsize,hjust = 0.5)
  )+
  xlab('City Initials')+
  ylab('Testing Value')

#dir.create('plot')
png('plot/plot4.png',
    height = 15, 
    width = 25,
    units = 'cm',
    res = 800)
print(p4)
dev.off()
图4 自定义字符串顺序后结果可视化

9. 总结

本篇主要解决了两个问题:

    1. 在字符串+数字/数字单独做横轴时,如何解决如1,11...等排序乱序的问题?
  • 2.如何打破R中内置排列规则,按照我们的需求自定义样本横轴排列顺序,如将Beijing, Shanghai排列到一起等?

10. 本文所用到package(若没有需要通过install.packages 进行安装)

library('ggplot2')

11. 致谢

首先,感谢大家的持续关注,小编会继续努力,持续更新下去的!

大家如果觉得有用,还麻烦大家关注点赞,也可以扩散到朋友圈,多谢大家啦~

大家如果在使用本文代码的过程有遇到问题的,可以留言评论,也可以私信我哈~~


小编联系方式
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容