实用技术 | 十分钟搞定哑铃图——R实现与论文复盘

2019年,一篇发在《自然》(Science)上的论文刷爆了中国网民的朋友圈。来自美国和瑞士的学者宣称,他们通过“丢钱包”的实地实验考察了全球数十个国家的民众诚信情况。数据表明,无论捡到的钱包里是否有钱,都极少有中国民众会主动联系失主,这反映中国民众的诚信情况在全球各国排名垫底。正如很多学者已经指出的那样,这篇文章的研究设计有很大的问题。特别是,他们在钱包中留下了失主姓名和电子邮件地址,这完全不符合中国普通民众的通讯习惯。在此,我们不再重复对这篇文章价值立场的批评。

我们的关注点是,这篇文章使用了一种非常直观的可视化方法——哑铃图(Dumbbell Plot),这在很大程度上推动了文章的广泛传播。事实上,哑铃图只是用直线连接了两组常规的点图,但却实现非常传神的数据表现效果。首先,阶梯状的排序清晰地展示了不同国家之间的差异。其次,两组数据点颜色和位置又直观刻画了变量在各国内部的关系。最后,连线显著减轻了读者在坐标系中匹配两个变量的视觉负担。

那么如何实现这种人见人爱的哑铃图呢?本文将为您逐步揭晓。

首先我们先根据文章末尾的提示找到原作者公开的资料。按要求填一下申请信息就可以下载数据和代码了。“behavior data”记录了“丢钱包”的详细数据。可以看到,原作者是Stata选手,而且已经贴心地给出了do文件。因此,我们就不重复Stata操作了,直接进入万物皆可R的环节(需要tidyverse包集群)。

作者给出的数据记录了每一次“丢钱包”的时间地点和结果,我们重点关注三个变量:国家Country、情形cond(放钱=1)、应答response(联系失主=100)。

方便起见,我们直接丢掉不关心的变量和样本。清洗后,我们需要将cond拆成两个变量然后将数据汇总到国家层面。这里有很多的简便方法和辅助工具,但我们仍然展示最基本的操作过程:

behavioral_data_csv_file_ <- read_csv("behavioral data (csv file).csv")test <- select(behavioral_data_csv_file_, Country, cond, response) %>% filter(cond < 2)test0 <- filter(test, cond == 0) %>% group_by(Country) %>% summarise(re0 = mean(response))test1 <- filter(test, cond == 1) %>% group_by(Country) %>% summarise(re1 = mean(response))test01 <- left_join(test0,test1)

现在我们已经得到了可以用来画图的汇总数据了。其中的变量分别为国家Country,钱包不放钱的应答率re0,钱包放钱的re1。

下面介绍最简单粗暴的一种作图方式,直接加载ggplot2的增强包ggalt(tidyverse不包含,需额外安装),此时以geom开头的几何层作图语法就多出了geom_dumbbell的选项。根据geom_dumbbell的逻辑,我们需要先根据一个连续变量和一个分类变量建立坐标系,然后再在坐标系中延伸出另一个连续变量。在我们的数据中,y理所当然的就是国家名。x则需要从re0和re1中选一个,这就是哑铃连线的起点,然后我们再把另一个变量定义给xend,这就是哑铃连线的终点。下面就是最基本的代码和惨不忍睹的第一张图。

library(ggalt)ggplot(test01,aes( y = Country,x = re0, xend = re1)) + geom_dumbbell()

下面开始调整图形。首先,我们要将国家有序排列,这就需要在ggplot的aes美学层命令中嵌入reorder函数。其次,我们需要用颜色将re0和re1分开。最后,我们希望哑铃能更饱满一些,然后希望背景不要喧宾夺主。

ggplot(test01,aes( y = reorder(Country, re0),x = re0, xend = re1)) +geom_dumbbell(size_x=2.5, size_xend = 2.5, colour_x="orange",colour_xend = "red") +theme_classic() + xlab("") +ylab("")     

现在看起来是不是舒服、清晰了很多?下面我们不妨进一步思考,哑铃图无非是点图和线图的组合,我们能不能只用最基本的ggplot命令来实现呢?答案是肯定的,而且在最基本的ggplot命令中,我们可以更加方便地批量化调整颜色、形状等属性。

下面贴出一种思路供大家参考:

test0101 <- arrange(test01, re0)test0101$o <- 1:40test0101 <- gather(test0101, key= cond, value = re, -c("Country","o"))ggplot(test0101, aes(y = reorder(Country,o), x = re, colour = cond, shape = cond )) +geom_line(aes(group = Country), colour = "black" ) +geom_point(size = 2.5) + theme_classic() + xlab("") +ylab("") 

最后,我们再看一个新的例子,读者可以自行从下面的思路和代码中体会细节。在《精英与大众双重视角下的当代欧洲民粹主义》一文中,作者希望描述欧洲各国民众对于移民的负面情绪。作者的数据中包括国家Cname,第四波调查结果immisum4,第五波调查结果immisum5,还有已经提前算好的国家排序X。

下面贴出同样提出两种实现哑铃图的代码和效果。

首先是ggalt选手:

e2 <- read_csv("e2.csv")ggplot(e2,aes(y = reorder(Cname, X), x = immisum4, xend = immisum5)) +geom_dumbbell(size_x=3.5, size_xend = 3.5, colour_x="skyblue",colour_xend = "red") +theme_bw() + xlab("") +ylab("")  + coord_flip() +theme(axis.text=element_text(angle = 90, colour = "black")) +theme(axis.text.y=element_text(size=0))

然后是最基本的ggplot命令:

 e3 <- gather(e2, key = colour, value = immi, -c("X","Cname")) ggplot(e3,aes(x = reorder(Cname,X), y = immi, colour = colour, shape = colour))+ geom_line(aes(group = Cname),colour = "black" ) + geom_point(size = 3.3)+ theme_bw()+xlab("") +ylab("")+ theme(axis.text.y=element_text(size=0)) + theme(legend.position="none")+ theme(axis.text=element_text(angle = 90, colour = "black"))

我们将本文的代码和相关数据打包上传到了网盘,感兴趣的读者朋友可以扫描下面二维码下载复验。

参考文献:

1. A. Cohn, et al., “Civic Honesty around the Globe,” Science, Vol. 365, No. 6448, 2019, pp. 70-73.

2. 陆屹洲、马得勇:《精英与大众双重视角下的当代欧洲民粹主义》,《中央社会主义学院学报》,2020年第6期,第47-60页。

撰文:陆屹洲  审读:杨端程  编辑:张天一

在看政观么

(0)

相关推荐

  • 《R数据可视化手册》之—善变的散点图

    作者:文艺 审核:文涛 <R数据可视化手册>之--善变的散点图 写在前面 散点图是文献中常见的可视化图形,同时也是基本可视化方式之一,在R语言中得到很好的支持,尤其是ggplot2.本小结 ...

  • ggdag:DAG和因果图

    近几年来,因果推断同时受到多个学科的重视,是最火热的研究方向之一.因果图(或称路径图)是研究因果关系的一个有效的辅助性工具.借助因果图可以分析因果关系,将复杂问题图形化.本文介绍一个用来绘制因果图的R ...

  • 数据处理基础—ggplot2了解一下

    书籍翻译 好的书籍是人类进步的阶梯,但有些人却找不到优秀的阶梯,为此我们开设了书籍翻译这个栏目,作为你学习之路的指路明灯:分享国内外优秀书籍,弘扬分享精神,做一个知识的传播者. 希望大家能有所收获! ...

  • 圣诞前送你们一朵使用ggplot画的玫瑰花

    library(tidyverse) 一只花柄 p <- ggplot() + coord_equal(1, c(-4, 2), c(-7, 3)) + geom_curve(aes(x = - ...

  • 【看图学拍】十分钟搞定直方图,新手必读!

    ◆ ◆ ◆ 图文源于网络 仅供学习交流用 我们在电脑上做后期,照片明暗影调的控制是很难把握的.如果没有一个Mac的显示器,恐怕你都不会太自信,怕你修的照片明暗不准确.那怎样才能准确?你真不知道!其实, ...

  • 快手又下饭的小炒菜,美味可口,十分钟搞定

    视频图文均为妖妖原创美食课堂原创作品,并已签约维权,以盈利为目的的抄袭,搬运必追究到底!喜欢我们的文章的读者,欢迎您关注我们,点赞,收藏,转发给更多的朋友学习,您的关注是我们持续更新的动力

  • 十分钟搞定!化学除磷剂的投加!

    所有的污水除磷方法都包含有两个必要的过程,首先将溶解性磷(磷酸盐)物质转化为不溶性悬浮(颗粒)性状态,然后通过固液分离将磷从污水中除去. 1.除磷剂的分类 除磷剂是向污水中投加化学药剂,使水中磷酸根离 ...

  • 早餐来碗十分钟搞定的清汤挂面,做法简单省时,口感清爽又营养

    说起清汤挂面,虽然很多人觉得很简单,但做出的却很难吃,甚至有的人认为做清汤面必须要用高汤(肉汤)做底料才会好吃,但做过饭的人都知道,想要炖煮一锅高汤最起码要1-2个小时,对于那些没有时间做早餐的上班族 ...

  • 记住这个酱香饼配方,家里手抓饼也能做,方法简单,十分钟搞定

    前段时间用家里剩余的手抓饼做了个简易版的肉夹馍,收到很多单身的粉丝的私信我,说我做的肉夹馍虽然比起传统的肉夹馍做法已经很简单了,但因为要卤肉就要1个多小时, 下班回家累得只想躺在床上,而且因为是1个人 ...

  • 厨房小白十分钟搞定家常菜-红烧土豆鸡翅!

    零失败的配方,简单容易上手,是妈妈的味道. 1. 材料: 鸡翅中:8只 土豆:3个(中等) 胡萝卜:1/3 根(可以不放) 2. 调料 大勺- 汤勺  小勺- 茶勺 美极酱油 : 三大勺 葡萄籽油- ...

  • 十分钟搞定,阳离子、阴离子、非离子PAM的区别及用途!

    聚丙烯酰胺(PAM)是一种线型水溶性高分子,是我们污水处理中最常用的一种药剂,没有之一!在我们实际应用中PAM又分为阳离子.阴离子还有非离子三种类型,如何选择这三类PAM,要从其中的区别说起! 1.结 ...

  • 十分钟搞定!——奶香焦糖布丁

    - 奶香焦糖布丁 - 原创作者 薄荷糖的味道818食材用料蛋黄3个淡奶油150g牛奶150g糖15g 1 /  奶油和糖一起称量 2 /  倒入糖 3 /  微波炉加热1分钟 4 /  倒入蛋黄 5  ...