使用ggplot2和facet_grid同时处理连续和分类变量 (R)

3

我正在尝试制作一系列类似于这样的图表:

enter image description here

我有一些混合分类和连续数据。当只有分类变量或只有连续变量时,我能够制作这一系列图表。但是当两种类型的变量同时存在时,我无法生成这一系列图表。

我已经创建了一些数据。请问是否有一种方法可以调试此代码,以便产生一系列图表?

library(ggplot2) 
library(gridExtra)
library(tidyr)

/create some data/

var_1 <- rnorm(100,1,4)
var_2 <- sample( LETTERS[1:2], 100, replace=TRUE, prob=c(0.3, 0.7) )
var_3 <- sample( LETTERS[1:5], 100, replace=TRUE, prob=c(0.2, 0.2,0.2,0.2, 0.1) )
cluster <- sample( LETTERS[1:4], 100, replace=TRUE, prob=c(2.5, 2.5, 2.5, 2.5) )

/put in a frame/

f <- data.frame(var_1, var_2, var_3, cluster)

/convert to factors/

f$var_2 = as.factor(f$var_2)
f$var_3 = as.factor(f$var_3)
f$cluster = as.factor(f$cluster)

/create graphs/

f2 %>% pivot_longer(cols = contains("var"), names_to = "variable") %>% 
    ggplot(aes(x = value, fill = value)) + 
    geom_bar() + geom_density() +
    facet_grid(rows = vars(cluster), 
               cols = vars(variable), 
               scales = "free") + 
    labs(y = "freq", fill = "Var")

当我只有分类变量时,以下代码可以使用:

var_2 <- sample( LETTERS[1:2], 100, replace=TRUE, prob=c(0.3, 0.7) )

var_3 <- sample( LETTERS[1:5], 100, replace=TRUE, prob=c(0.2, 0.2,0.2,0.2, 0.1) )

cluster <- sample( LETTERS[1:4], 100, replace=TRUE, prob=c(2.5, 2.5, 2.5, 2.5) )

f <- data.frame(var_2, var_3, cluster)
f$var_2 = as.factor(f$var_2)
f$var_3 = as.factor(f$var_3)
f$cluster = as.factor(f$cluster)

f%>% pivot_longer(cols = contains("var"), names_to = "variable") %>% ggplot(aes(x = value, fill = value)) + geom_bar() + geom_density() +facet_grid(rows = vars(cluster), cols = vars(variable), scales = "free") + labs(y = "freq", fill = "Var")
2个回答

2
我认为ggplot无法同时处理连续和分类变量在y或x的美学特征中。但是,在pivot_longer()中混合它们时也会出现错误。
错误:无法组合var_1和var_2。
我的建议是为每个指标创建单独的图,然后将这些图组合起来。这将使您更好地控制每个图。这里有一个使用GGally的ggmatrix()的示例。我相信这也可以用gridextra实现。
library(ggplot2)
library(gridExtra)
library(tidyr)
library(GGally)

# Generate data
var_1 <- rnorm(100, 1, 4)
var_2 <- sample(LETTERS[1:2], 100, replace = TRUE, prob = c(0.3, 0.7))
var_3 <- sample(LETTERS[1:5], 100, replace = TRUE, prob = c(0.2, 0.2, 0.2, 0.2, 0.1))
cluster <- sample(LETTERS[1:4], 100, replace = TRUE,prob = c(2.5, 2.5, 2.5, 2.5))

f <- data.frame(var_1, var_2, var_3, cluster)

f$var_2 = as.factor(f$var_2)
f$var_3 = as.factor(f$var_3)
f$cluster = as.factor(f$cluster)

# Create plots for each var
var_1_plot <- f %>%
  ggplot(aes(x = var_1,
             fill = cluster)) +
  geom_density() +
  facet_grid(cluster ~ .,
             scales = "free")
var_2_plot <- f %>%
  ggplot(aes(x = var_2,
             fill = cluster)) +
  geom_bar() +
  facet_grid(cluster ~ .,
             scales = "free")

var_3_plot <- f %>%
  ggplot(aes(x = var_3,
             fill = cluster)) +
  geom_bar() +
  facet_grid(cluster ~ .,
             scales = "free")

# Combine all plots
plot_list <- list(var_1_plot, var_2_plot, var_3_plot)
GGally::ggmatrix(
  plots = plot_list,
  nrow = 1,
  ncol = 3,
  xAxisLabels = c("Var 1", "Var 2", "Var 3"),
)

enter image description here


谢谢!我在办公电脑上没有ggally。我只能下载选定的库。是否可能仅使用ggplot2完成此操作?我最接近的是这里:f_cont = f[,c(1:4)] f_cat=f[,c(2:4)]     a = ggplot(data = f_cont, aes(x = var_1)) + geom_density(alpha=0.6) + facet_wrap( ~ cluster)b = f_cat%>% pivot_longer(cols = contains("var"), names_to = "variable") %>% ggplot(aes(x = value, fill = value)) + geom_bar() + geom_density() +facet_grid(rows = vars(cluster), cols = vars(variable), scales = "free") + labs(y = "freq", fill = "Var")a + b grid.arrange(a,b) - stats_noob
哦,我明白了。看起来 @Allan Cameron 使用纯 ggplot2 有一个解决方案。 - David
@DavidGibson:你能否看一下我的问题?https://stackoverflow.com/questions/65676788/combining-different-types-of-graphs-together-r 谢谢! - stats_noob

1
这是完全在ggplot内实现的可能性,但这相当于hacky。Facet实际上是显示同一数据集的额外维度的一种方式。它们并不旨在成为任意拼合不同图表的方法,因此完全基于ggplot的解决方案需要操纵数据和轴标签以产生图表拼接的外观。
首先,我们将酒吧情节变量的唯一水平作为字符字符串获取:
levs    <- sort(unique(c(as.character(f$var_2), as.character(f$var_3))))

现在,我们将这些因素转换为数字:
f$var_2 <- as.numeric(factor(f$var_2, levs)) + ceiling(max(f$var_1)) + 10
f$var_3 <- as.numeric(factor(f$var_3, levs)) + ceiling(max(f$var_1)) + 10

我们现在将构建用于x轴的间断和标签。
breaks  <- c(pretty(range(f$var_1)), sort(unique(c(f$var_2, f$var_3))))
labs    <- c(pretty(range(f$var_1)), levs)

现在我们可以安全地旋转我们的数据框:
f <- pivot_longer(f, cols = c("var_1", "var_2", "var_3")) 

对于我们的图表,我们将使用从数据框中适当子集化的组来制作密度图和条形图。然后,我们使用自由比例进行分面,并用预定义的间隔和标签标记x轴:

ggplot(f, aes(x = value)) +
  geom_density(data = subset(f, name == "var_1")) +
  geom_bar(data = subset(f, name != "var_1"), aes(fill = name)) +
  facet_wrap(cluster~name, ncol = 3, scales = "free") +
  scale_x_continuous(breaks = breaks, labels = labs) +
  scale_fill_manual(values = c("deepskyblue4", "gold"), guide = guide_none())

enter image description here


我有两个问题:假设有多个连续变量,代码能修改吗?是否有一种方法可以更改 aes(),使得同一图表中的条形以不同的颜色按类别着色?var_1 <- rnorm(100,1,4) var_4 <- rnorm(100,1,3) var_2 <- sample( LETTERS[1:2], 100, replace=TRUE, prob=c(0.3, 0.7) ) var_3 <- sample( LETTERS[1:5], 100, replace=TRUE, prob=c(0.2, 0.2,0.2,0.2, 0.1) ) cluster <- sample( LETTERS[1:4], 100, replace=TRUE, prob=c(2.5, 2.5, 2.5, 2.5) )f <- data.frame(var_1, var_2, var_3, var_4, cluster) .... 还能正常工作吗?谢谢! - stats_noob
@Allan Cameron:你能否请看一下我的问题?https://stackoverflow.com/questions/65676788/combining-different-types-of-graphs-together-r 谢谢! - stats_noob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接