連続変数とカテゴリ変数にggplot2とfacet_gridを一緒に使用する(R)

Aug 23 2020

私は次のような一連のグラフを作成しようとしています。

カテゴリデータと連続データが混在しています。この一連のグラフは、カテゴリ変数しかない場合、または連続変数しかない場合に作成できます。しかし、両方のタイプの変数がある場合、この一連のグラフを作成することはできません。

以下にいくつかのデータを作成しました。このコードをデバッグして一連のグラフを生成する方法はありますか?

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")

回答

AllanCameron Aug 23 2020 at 17:18

これ完全にggplot内で行うことできますが、かなりハッキーです。ファセットは、実際には同じデータセットの追加のディメンションを表示する方法です。これらは、異なるプロットを任意につなぎ合わせる方法を意図したものではないため、完全にggplotベースのソリューションでは、データと軸ラベルを操作して、つなぎ合わせたプロットの外観を作成する必要があります。

まず、barplot変数の一意のレベルを文字列として取得します。

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())

1 DavidGibson Aug 23 2020 at 13:23

ggplotは、yまたはx 美学の連続変数とカテゴリ変数の両方を処理できるとは思いません。ただし、でそれらを混合するとエラーも発生しますpivot_longer()

Error: Can't combine `var_1` <double> and `var_2` <character>.

メトリックごとに個別のプロットを作成してから、プロットを結合することをお勧めします。これにより、各プロットをより細かく制御できます。これは、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"),
)