固定 ggplot 中切面的顺序

资料:

df <- data.frame(
type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"),
size   = c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"),
amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)

我需要使用 ggplot (x 轴-> type,y 轴-> amount,group by size)绘制上述数据的条形图。当我使用以下代码时,我没有按照数据中显示的顺序得到变量 typesize。请看图。我使用了以下代码。

 ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) +
geom_col(width=0.5, position = position_dodge(width=0.6)) +
facet_grid(.~size) +
theme_bw() +
scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"),
labels = c("T", "F", "P"))

enter image description here.

为了解决订单问题,我使用以下方法对变量“ type”使用 factor 方法。请看这个图。

temp$new = factor(temp$type, levels=c("T","F","P"), labels=c("T","F","P"))

enter image description here

然而,现在我不知道如何修正变量 size的顺序。应该是50% ,100% 。150% 和200% 。

171807 次浏览

通过以下方法使你的尺寸成为数据框中的一个因素:

temp$size_f = factor(temp$size, levels=c('50%','100%','150%','200%'))

然后将 facet_grid(.~size)改为 facet_grid(.~size_f)

然后情节是: enter image description here

图表现在按正确的顺序排列。

这里有一个解决方案,可以将事物保持在 dplyr 管道链中。可以预先对数据进行排序,然后使用 mutate _ at 将其转换为一个因子。我稍微修改了一下数据,以展示如何通用地应用这个解决方案,给定可以合理排序的数据:

# the data
temp <- data.frame(type=rep(c("T", "F", "P"), 4),
size=rep(c("50%", "100%", "200%", "150%"), each=3), # cannot sort this
size_num = rep(c(.5, 1, 2, 1.5), each=3), # can sort this
amount=c(48.4, 48.1, 46.8,
25.9, 26.0, 24.9,
20.8, 21.5, 16.5,
21.1, 21.4, 20.1))


temp %>%
arrange(size_num) %>% # sort
mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>% # convert to factor


ggplot() +
geom_bar(aes(x = type, y=amount, fill=type),
position="dodge", stat="identity") +
facet_grid(~ size)

您也可以应用此解决方案来排列方面内的条形,尽管您只能选择一个首选顺序:

    temp %>%
arrange(size_num) %>%
mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>%
arrange(desc(amount)) %>%
mutate_at(vars(type), funs(factor(., levels=unique(.)))) %>%
ggplot() +
geom_bar(aes(x = type, y=amount, fill=type),
position="dodge", stat="identity") +
facet_grid(~ size)




ggplot() +
geom_bar(aes(x = type, y=amount, fill=type),
position="dodge", stat="identity") +
facet_grid(~ size)

这里有几个很好的解决方案。

与 Harpal 的答案相似,但是在这个方面,所以 不需要对基础数据或预绘图操作进行任何更改:

# Change this code:
facet_grid(.~size) +
# To this code:
facet_grid(~factor(size, levels=c('50%','100%','150%','200%')))

这是灵活的,可以实现为任何变量,因为您更改什么元素是面,没有基本的变化的数据需要。

更少的操纵: facet_grid(~fct_relevel(size,'50%','100%','150%','200%'))

类似于 Glenn _ in _ boston 的回答,但是没有在级别中进行硬编码。

# Change this code:
facet_grid(.~size) +
# To this code:
facet_grid(~factor(size, levels=unique(df$size)))

因为大小是按照数据框架中从最小到最大的顺序排列的。

如果尺寸已经是一个因素,并且在绘图时只想翻转顺序,那么可以这样选择:

# Updating dataframe so size is a factor ordered smallest to largest
df <- data.frame(
type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"),
size   = factor(c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"), levels=c("50%", "100%","150%","200%"), ordered = TRUE),
amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)


# Now plotting with facets in the reverse order
ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) +
geom_col(width=0.5, position = position_dodge(width=0.6)) +
facet_grid(~factor(size, levels=rev(unique(df$size)))) +  #this part updated
theme_bw() +
scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"),
labels = c("T", "F", "P"))

无需解析标签或修改原始数据,也无需使用 stringr::str_sort( , numeric = TRUE)手工确定订单,就可以实现包租面标签的数字订购:

... +

facet_grid(. ~ factor( , stringr::str_sort(unique( ), numeric = TRUE))) +

...


完整的例子:

library(ggplot2)


df <- data.frame(
type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"),
size   = c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"),
amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)


ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) +
geom_col(width=0.5, position = position_dodge(width=0.6)) +
facet_grid(.~factor(size, stringr::str_sort(unique(size), numeric = TRUE))) +
theme_bw() +
scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"),
labels = c("T", "F", "P"))

Reprex 软件包于2022.03-11创作(v2.0.1)

通常,就像在这种情况下,指定方面顺序的愿望根源于它们表示一些有序数据。在这种情况下,最好首先正确地清理数据,即解析字符列中的数值。在这种情况下,可以很容易地做与 df$size <- as.numeric(sub("%", "", df$size))/100。然后可以使用一个标记函数来控制 facet 标签,例如 facet_grid(.~size, labeller = function(x) lapply(x, scales::label_percent()))

library(ggplot2)


df <- data.frame(
type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"),
size   = c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"),
amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)


df$size <- as.numeric(sub("%", "", df$size))/100


ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) +
geom_col(width=0.5, position = position_dodge(width=0.6)) +
facet_grid(.~size, labeller = function(x) lapply(x, scales::label_percent())) +
theme_bw() +
scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"),
labels = c("T", "F", "P"))

Reprex 软件包于2022.03-11创作(v2.0.1)