我正试图在多个地区建立一个人口金字塔。问题是,这些地区的人口规模有很大的不同,造成了y轴上的比例问题(coord翻转)。
我试图遵循这里描述的方法:ggplot2 --通过对一种性别使用负数来创建金字塔,然后使用scale_y_continuous()去除负数。
首先,我为两个国家的两个年龄组创建了一个简单的样本数据集:
country <- c(1, 1, 1, 1, 2, 2, 2, 2)
age.range <- c("0-4", "0-4", "5-9", "5-9", "0-4", "0-4", "5-9", "5-9")
sex <- rep(c("M", "F"), times = 4)
pop <- c(-8, 9, -9, 8, -88, 99, -99, 88)
pop.pyr <- data.frame(country, age.range, sex, pop)
pop.pyr
country age.range sex pop
1 1 0-4 M -8
2 1 0-4 F 9
3 1 5-9 M -9
4 1 5-9 F 8
5 2 0-4 M -88
6 2 0-4 F 99
7 2 5-9 M -99
8 2 5-9 F 88我可以按国家建立人口金字塔和方面:
library(ggplot2)
ggplot(pop.pyr, aes(x = age.range, y = pop, fill = sex)) +
geom_col(data = subset(pop.pyr, sex == "M")) +
geom_col(data = subset(pop.pyr, sex == "F")) +
coord_flip() +
facet_wrap(~ country, scales = "free_x")

要在y-scale (coord_flip())上修正负数,我需要使用:scale_y_continuous();但是这样做意味着我必须为两个方面选择一个scale_y_continuous(),这是行不通的。
ggplot(pop.pyr, aes(x = age.range, y = pop, fill = sex)) +
geom_col(data = subset(pop.pyr, sex == "M")) +
geom_col(data = subset(pop.pyr, sex == "F")) +
coord_flip() +
facet_wrap(~ country, scales = "free_x") +
scale_y_continuous(breaks = seq(-100, 100, 20), labels = abs(seq(-100, 100, 20)))

唯一的解决办法是在by中为seq (例如scale_y_continuous(breaks = seq(-100, 100, 2), labels = abs(seq(-100, 100, 2))) )使用一个小变量。然而,这样做会使更大的规模变得一团糟。
是否有一种方法可以使scale_y_continuous()在不同方面具有不同的规模,同时保持:scales = free_x。否则,还有另一种方法可以用scale_y_continuous()以外的东西来消除金字塔中的负数。
如果不是,那么唯一的方法是单独开发每幅图像,然后是ggarrange()或cowplot() --基本上是手动处理?
编辑:
我试着按照注释使用facetscales(),但是我无法让它以我想要的方式工作,也无法完全理解这个man文件。
使用这里的说明:https://github.com/zeehio/facetscales;我安装并加载了包
library(facetscales)然后我创建了比例列表:
scales.pyr <- list(`1` = scale_y_continuous(breaks = seq(-10, 10, 2), labels = abs(seq(-10, 10, 2))), `2` = scale_y_continuous(breaks = seq(-100, 100, 20), labels = abs(seq(-100, 100, 20))))更新ggplot:
ggplot(pop.pyr, aes(x = age.range, y = pop, fill = sex)) +
geom_col(data = subset(pop.pyr, sex == "M")) +
geom_col(data = subset(pop.pyr, sex == "F")) +
coord_flip() +
facet_grid_sc(rows= vars(country), scales = list(y = scales.pyr))

这显然是不对的。man文件(sc.Rd)说我可以使用cols:
facet_grid_sc(rows = NULL,cols = NULL,scales =“固定”,空格=“固定”,收缩=真,标记器= "label_value",as.table =真,开关=空,降=真,边距=假,面=空) ..。 \item{cols}{ \code{\link=vars{vars()}}引用的一组变量或表达式,并在行或列维度上定义平面组。变量可以命名(名称传递给\code{labeller})。
如果我尝试科尔:
ggplot(pop.pyr, aes(x = age.range, y = pop, fill = sex)) +
geom_col(data = subset(pop.pyr, sex == "M")) +
geom_col(data = subset(pop.pyr, sex == "F")) +
coord_flip() +
facet_grid_sc(cols= vars(country), scales = list(y = scales.pyr))我得到:
Error in .subset2(x, i, exact = exact) :
attempt to select less than one element in get1index同样清楚的是,刻度是固定的,手册页同样说我可以使用scales = "free"或折旧的"free_x"。
{两个元素(
x和y)的列表。每个元素可以是"fixed"(跨方面共享的缩放限制)、"free"(每个方面的限制各不相同),也可以是命名列表,每个方面的值都有不同的标度。以前的标度值("fixed"、"free_x"、"free_y"、"free"被接受,但不推荐使用)。
但是,代码示例要求scales参数填充刻度列表。
最后,我真的想把六个区域分成两行三行。手册页指出,我可以使用行和cols来划分不同的变量,但是我看不到对单个变量的nrow(),ncol()的任何引用。在一个更大的例子中使用它们可以得到:unused argument (ncol = 3)。
发布于 2019-01-16 23:21:33
答案很简单:使用scale_y_continuous(labels = abs)。最终代码如下:
country <- c(1, 1, 1, 1, 2, 2, 2, 2)
age.range <- c("0-4", "0-4", "5-9", "5-9", "0-4", "0-4", "5-9", "5-9")
sex <- rep(c("M", "F"), times = 4)
pop <- c(-8, 9, -9, 8, -88, 99, -99, 88)
pop.pyr <- data.frame(country, age.range, sex, pop)
library(ggplot2)
ggplot(pop.pyr, aes(x = age.range, y = pop, fill = sex)) +
geom_col() +
coord_flip() +
scale_y_continuous(labels = abs)
facet_wrap(~ country, scales = "free_x")

那是一段漫长的路。谢谢@Z.Lin。
发布于 2022-07-26 09:39:06
我认为现在可以在ggh4x库(scales.html)中使用scales.html了。
https://stackoverflow.com/questions/54207750
复制相似问题