(R) Înțelegerea position_dodge() și position_dodge2() în ggplot2

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

Blogul lui Zhenguo Zhang https://fortune9.netlify.app/2026/08/30/r-understanding-position-dodge-and-position-dodge2-in-ggplot2/ –

În ggplot2când se afișează date grupate de-a lungul axelor categoriale (cum ar fi diagrame cu bare grupate, diagrame cu case sau bare de eroare), evitarea orizontală este utilizată pentru a preveni suprapunerea elementelor la fiecare poziție categorială. ggplot2 oferă două funcții principale de poziție de eschiv: position_dodge() şi position_dodge2().

În această postare, vom explora:

  1. Cum width parametrul in position_dodge() interacționează cu geom-ul părinte width.
  2. Diferențele de bază dintre position_dodge2() şi position_dodge()inclusiv de ce se schimbă width în position_dodge2() adesea nu are efect vizual.
  3. Cum preserve = "single" se comportă atunci când elementele unei variabile de grup lipsesc la un anumit nivel al axei x.

Definiția termenilor

Pentru a menține explicațiile noastre clare și consecvente pe parcursul acestei postări, definim două concepte cheie:

  • nivelul axei x: Valoarea sau categoria discretă pe axa x. În exemplele noastre folosind mtcarsnivelul axei x este cyl (cu niveluri 4, 6și 8).
  • variabila de grup: variabila care împarte articolele în subgrupuri la fiecare nivel de axa x, de obicei mapată la un aspect estetic fill sau color. În exemplele noastre, variabila de grup este gear (cu niveluri 3, 4și 5).
  • elemente eschivate: marcajele vizuale individuale (de ex. bare) corespunzătoare fiecărui nivel al variabilei de grup la un anumit nivel pe axa x.
library(ggplot2)
library(patchwork)

1. Cel width Parametrul in position_dodge()

Ce face width controla?

În position_dodge(width = ...), width specifică durata totală de eschivare (interval) pe axa x în care toate elementele eschivate pentru un anumit nivel a axei x sunt dispuse una lângă alta.

În mod implicit, dacă nu furnizați în mod explicit width la position_dodge()ea își moștenește valoarea de la geom-ul părinte (de exemplu, geom_bar() implicit la width = 0.9).

Interacțiunea dintre geom_bar(width) şi position_dodge(width)

  • geom_bar(width = ...): Setează lățimea fizică totală alocată barelor la fiecare nivel al axei x. Lățimea individuală a barei este derivată prin împărțirea acestei valori la numărul de elemente de la acel nivel al axei x.
  • position_dodge(width = ...): Setează distanța totală pe axa x de-a lungul căreia sunt calculate și distanțate pozițiile centrale ale elementelor evitate.

Ambii parametri folosesc unități de coordonate pe axa x (unde distanța dintre nivelurile discrete axa x adiacente este 1.0).

Să examinăm modul în care variația ambilor parametri afectează aspectul folosind mtcars set de date (media grafică mpg peste nivelul axei x cylcu variabila de grup gear mapat la fill):

# Base plot configuration
base_p <- ggplot(mtcars, aes(x = factor(cyl), y = mpg, fill = factor(gear))) +
  labs(x = "Cylinders (x-axis level)", y = "Mean MPG", fill = "Gear (group variable)") +
  theme_minimal(base_size = 11)

# Case 1: Default matching widths (0.9 / 0.9)
# Bars touch neatly within each x-axis level
p1 <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    width = 0.9, 
    position = position_dodge(width = 0.9)
  ) +
  ggtitle("1. Matching widths (0.9 / 0.9)", subtitle = "Bars touch neatly within each x-axis level")

# Case 2: geom_bar width (0.5) < dodge width (0.9)
# Dodging span is 0.9, but bars are narrower -> gaps appear between bars
p2 <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    width = 0.5, 
    position = position_dodge(width = 0.9)
  ) +
  ggtitle("2. geom_bar(0.5) < dodge(0.9)", subtitle = "Gaps created between dodged elements")

# Case 3: geom_bar width (0.9) > dodge width (0.5)
# Dodging span is narrower than bar widths -> bars overlap
p3 <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    width = 0.9, 
    position = position_dodge(width = 0.5)
  ) +
  ggtitle("3. geom_bar(0.9) > dodge(0.5)", subtitle = "Dodged elements overlap")

# Case 4: Both changed to 0.6
# Group as a whole is narrower, bars touch, larger separation between x-axis levels
p4 <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    width = 0.6, 
    position = position_dodge(width = 0.6)
  ) +
  ggtitle("4. Both set to 0.6", subtitle = "Compact cluster, wider space between x-axis levels")

(p1 | p2) / (p3 | p4)

După cum sa demonstrat: – Creștere width în geom_bar() mărește lățimea individuală a elementelor evitate la acel nivel al axei x. – Creste width în position_dodge() mărește intervalul total de eschivare pe care sunt răspândite elementele. – Când ambele valori sunt egale, elementele ocolite din fiecare nivel de axa x se ating între ele fără a se suprapune sau a lăsa goluri.


2. Diferențele între position_dodge2() şi position_dodge()

în timp ce position_dodge() a fost conceput inițial pentru geomuri simple cu poziții cu lățime fixă ​​(cum ar fi geom_bar şi geom_col), position_dodge2() a fost introdus pentru a gestiona geoms cu lățimi variabile sau intervale explicite (xmin la xmax), ca geom_boxplot(), geom_rect()și geom_linerange().

Diferențele cheie:

  1. Ambalare bazată pe limită vs. Compensarea sloturilor fixe:
    • position_dodge() împarte lățimea totală de eschivare la nivelul axei x în sloturi fixe și plasează fiecare nivel al variabilei de grup în slotul său desemnat.
    • position_dodge2() împachetează elemente (pentru diferite niveluri ale variabilei de grup) secvenţial unul lângă altul folosind casetele de delimitare ale geoms-urilor.
  2. The width Parametrul nu are efect vizual în position_dodge2() cu Baruri:
    • Deoarece position_dodge2() aranjează barele pe baza intervalelor lor de delimitare precalculate, mai degrabă decât să calculeze decalajele slotului central dintr-un interval de eschivare, schimbând width în position_dodge2() nu produce nicio modificare în rezultatul graficului atunci când lățimile barelor sunt deja definite de geom-ul părinte.
    • Lățimile barelor trebuie controlate direct prin geom_bar(width = ...).
  3. Încorporat padding şi reverse Sprijin:
    • padding: Adaugă spațiu proporțional între elementele eschivate la același nivel al axei x, fără a necesita nepotrivirea manuală a lățimilor de geom și de eschiv.
    • reverse = TRUE: inversează ordinea de reprezentare de la stânga la dreapta a variabilei de grup fără a fi nevoie să se modifice nivelurile factorilor.

Demo: width Nu are efect în position_dodge2()

Mai jos, comparăm position_dodge2(width = 0.3) împotriva position_dodge2(width = 0.9). Observați că cele două diagrame sunt complet identice:

# Changing width in position_dodge2 produces identical output
p_d2_w03 <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    position = position_dodge2(width = 0.3)
  ) +
  ggtitle("position_dodge2(width = 0.3)", subtitle = "Width parameter has no visual effect")

p_d2_w09 <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    position = position_dodge2(width = 0.9)
  ) +
  ggtitle("position_dodge2(width = 0.9)", subtitle = "Identical layout to width = 0.3")

p_d2_w03 | p_d2_w09

Crearea spațiere cu padding și inversarea ordinii cu reverse

În loc să modifice width, position_dodge2() oferă padding şi reverse parametri:

# Using padding and reverse in position_dodge2
p_dodge2_demo <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    position = position_dodge2(padding = 0.2, reverse = TRUE)
  ) +
  labs(
    title = "position_dodge2(padding = 0.2, reverse = TRUE)",
    subtitle = "Built-in bar padding and reversed order of group variable"
  )

p_dodge2_demo


3. Manipularea elementelor lipsă cu preserve = "single"

O diferență funcțională semnificativă între position_dodge() şi position_dodge2() apare atunci când anumite niveluri ale variabilei de grup sunt absente la un nivel specific pe axa x.

Să inspectăm numărul de observații de-a lungul cyl (nivelul axei x) și gear (variabila de grup) in mtcars:

table(mtcars$cyl, mtcars$gear)
##    
##      3  4  5
##   4  1  8  2
##   6  2  4  1
##   8 12  0  2

La nivelul axei x cyl = 8variabila de grup gear conţine observaţii pentru angrenaje 3 (12 mașini) și 5 (2 mașini), dar gear = 4 lipsește complet (0 mașini).

Când stabilim preserve = "single" pentru a vă asigura că toate lățimile individuale ale barelor rămân uniforme pe toate nivelurile axei x:

  • position_dodge(preserve = "single"): Păstrează alocările de slot fixe. Deoarece gear = 4 lipsește la cyl = 8lasa a gol gol la mijloc unde gear = 4 ar locui în mod normal.
  • position_dodge2(preserve = "single"): Păstrează lățimea barei individuale în timp ce recentrând elementele eschivate rămaseîmpachetându-le unul lângă altul fără a lăsa un gol.
# position_dodge with preserve = "single"
p_dodge_single <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    position = position_dodge(preserve = "single")
  ) +
  labs(
    title = "position_dodge(preserve = 'single')",
    subtitle = "Leaves an empty gap for missing gear = 4 at cyl = 8"
  )

# position_dodge2 with preserve = "single"
p_dodge2_single <- base_p +
  geom_bar(
    stat = "summary", 
    fun = "mean", 
    position = position_dodge2(preserve = "single")
  ) +
  labs(
    title = "position_dodge2(preserve = 'single')",
    subtitle = "Re-centers remaining elements (no gap at cyl = 8)"
  )

# Side-by-side comparison
p_dodge_single | p_dodge2_single

Rețineți că dacă setați preserve = „total”, atunci nu veți vedea nicio diferență, deoarece barele sunt reîntinse pentru a vă asigura că barele de la fiecare nivel categorial ocupă toată lățimea atribuită acelui nivel.


Rezumat

Cazuri de utilizare primară Geome simple 1D cu lățime fixă ​​(geom_bar, geom_col) Interval și geome cu lățime variabilă (geom_boxplot, geom_rect, geom_linerange) și bare
Rolul de width Parametru Setează intervalul total de eschivare pe fiecare nivel al axei x Nu are niciun efect vizual asupra barelor cu lățime geom predefinită
Elemente lipsă (preserve="single") Lasă slotul gol / gol la nivelul lipsă Recentrează împreună elementele eschivate rămase
Umplutură între elemente Manual (geom_bar(width) < position_dodge(width)) Încorporat prin padding = ... argument
Ordine inversă de trasare Necesită renivelarea variabilei de grup Încorporat prin reverse = TRUE argument

– https://fortune9.netlify.app/2026/08/30/r-understanding-position-dodge-and-position-dodge2-in-ggplot2/ –

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.