ggplot2 menambahkan data dari bingkai data tambahan di sebelah plot

Saya ingin memperluas plot kotak saya dengan informasi tambahan. Berikut adalah contoh kerja untuk ggplot2:

library(ggplot2)

ToothGrowth$dose <- as.factor(ToothGrowth$dose)

# Basic box plot
p <- ggplot(ToothGrowth, aes(x=dose, y=len)) + 
  geom_boxplot()
# Rotate the box plot
p + coord_flip()

Saya ingin menambahkan informasi tambahan dari bingkai data terpisah. Misalnya:

extra <- data.frame(dose=factor(c(0.5,1,2)), label=c("Label1", "Label2", "Label3"), n=c("n=42","n=52","n=35"))

> extra
  dose  label    n
1  0.5 Label1 n=42
2    1 Label2 n=52
3    2 Label3 n=35

Saya ingin membuat gambar berikut di mana informasi untuk setiap dosis (faktor) berada di luar plot dan selaras dengan masing-masing tingkat dosis (saya membuat ini di powerpoint sebagai contoh):

masukkan deskripsi gambar di sini

Setiap saran sangat dihargai!

Salam, Lukas

EDIT: Terima kasih banyak atas jawaban Anda! Sempurna. Saya ingin meminta saran untuk perpanjangan pertanyaan awal.

Bagaimana dengan ekstensi ini di mana saya menggunakan isi untuk membagi dosis oleh kedua kelompok?

ToothGrowth$dose <- as.factor(ToothGrowth$dose)
ToothGrowth$group <- head(rep(1:2, 100), dim(ToothGrowth)[1])
ToothGrowth$group <- factor(ToothGrowth$group)

 p <- ggplot(ToothGrowth, aes(x=dose, y=len, fill=group)) + 
     geom_boxplot()
 # Rotate the box plot
 p + coord_flip()

extra <- data.frame(
  dose=factor(rep(c(0.5,1,2), each=2)), 
  group=factor(rep(c(1:2), 3)), 
  label=c("Label1A", "Label1B", "Label2A", "Label2B", "Label3A", "Label3B"), 
  n=c("n=12","n=30","n=20", "n=32","n=15","n=20")
)

Apakah mungkin untuk menyelaraskan data dari kerangka data baru (ekstra, 6 baris) dengan masing-masing kombinasi dosis/kelompok?

Selamat, Luc


person Luc    schedule 09.08.2018    source sumber


Jawaban (1)


Kita dapat menggunakan geom_text dengan clip = "off" di dalam coord_flip:

ggplot(ToothGrowth, aes(x=dose, y=len)) +
    geom_boxplot() +
    geom_text(
        y = max(ToothGrowth$len) * 1.1,
        data = extra,
        aes(x = dose, label = sprintf("%s\n%s", label, n)),
        hjust = 0) +
    coord_flip(clip = "off") +
    theme(plot.margin = unit(c(1, 5, 0.5, 0.5), "lines"))

masukkan deskripsi gambar di sini

Penjelasan: Kami menempatkan teks di luar area plot dengan geom_text dan menonaktifkan kliping dengan clip = "off" di dalam coord_flip. Terakhir, kami meningkatkan margin plot untuk mengakomodasi label tambahan. Anda dapat mengatur posisi vertikal y di margin (jadi posisi horizontal di plot karena pembalikan koordinat) dengan mengubah faktor di y = max(ToothGrowth$len) * 1.1.


Menanggapi hasil edit Anda, inilah kemungkinannya

extra <- data.frame(
  dose=factor(rep(c(0.5,1,2), each=2)),
  group=factor(rep(c(1:2), 3)),
  label=c("Label1A", "Label1B", "Label2A", "Label2B", "Label3A", "Label3B"),
  n=c("n=12","n=30","n=20", "n=32","n=15","n=20")
)

library(tidyverse)
ToothGrowth %>%
    mutate(
        dose = as.factor(dose),
        group = as.factor(rep(1:2, nrow(ToothGrowth) / 2))) %>%
    ggplot(aes(x = dose, y = len, fill = group)) +
    geom_boxplot(position = position_dodge(width = 1)) +
    geom_text(
        data = extra %>%
            mutate(
                dose = as.factor(dose),
                group = as.factor(group),
                ymax = max(ToothGrowth$len) * 1.1),
        aes(x = dose, y = ymax, label = sprintf("%s\n%s", label, n)),
        position = position_dodge(width = 1),
        size = 3,
        hjust = 0) +
    coord_flip(clip = "off", ylim = c(0, max(ToothGrowth$len))) +
    theme(
        plot.margin = unit(c(1, 5, 0.5, 0.5), "lines"),
        legend.position = "bottom")

masukkan deskripsi gambar di sini

Beberapa komentar:

  1. Kami memastikan bahwa label cocok dengan bilah yang dihindari dengan menggunakan position_dodge(with = 1) di dalam geom_text dan geom_boxplot.
  2. Tampaknya position_dodge tidak menyukai y global (di luar aes). Jadi kita memasukkan posisi y untuk label di extra dan menggunakannya di dalam aes. Akibatnya, kita perlu membatasi rentang sumbu y secara eksplisit. Kita bisa melakukannya di dalam coord_flip dengan ylim = c(0, max(ToothGrowth$len)).
person Maurits Evers    schedule 09.08.2018
comment
Terima kasih banyak! Persis apa yang saya butuhkan! - person Luc; 10.08.2018
comment
Hai Maurits, bisakah Anda melihat masalah saya yang lebih luas? Lihat hasil edit di postingan asli. - person Luc; 10.08.2018
comment
Anda adalah seorang legenda! - person Luc; 10.08.2018