2014-12-14 19 views
5

Mam działkę, której etykiety są czynnikami w postaci "1990-2012". Są za długie i/lub jest ich zbyt wiele i nakładają się na siebie.Podział etykiet na 2 linie w ggplot z czynnikami

enter image description here

chciałbym wydrukować każdą etykietę na dwóch liniach i złamać go po myślniku, coś takiego:

enter image description here

W sytuacjach, w których łamanie etykiety na dwie części nadal nie wystarczy, chciałbym również wiedzieć, jak wydrukować tylko każdą inną etykietę.

Mam ograniczenie polegające na tym, że etykietowanie powinno odbywać się "na miejscu" bez wstępnego przetwarzania danych.frame i/lub etykiet, chociaż niestandardowa funkcja zastosowana w wywołaniu ggplot byłaby w porządku.

Oto święte dataframe (nie można zmienić):

df <- structure(list(Period = structure(1:13, .Label = c("0-1000", 
    "1000-1500", "1500-1700", "1700-1820", "1820-1913", "1913-1950", 
    "1950-1970", "1970-1990", "1990-2012", "2012-2030", "2030-2050", 
    "2050-2070", "2070-2100"), class = "factor"), value = c(0.000168759866884916, 
    0.000989913144738397, 0.00159894629454382, 0.0045594248070473, 
    0.00585564273031225, 0.00932876890888812, 0.0191066122563939, 
    0.0183146076484786, 0.0130117469870081, 0.00923670910453378, 
    0.00560791817163286, 0.00272731553972227, 0.00149387241891397 
    ), variable = c("World", "World", "World", "World", "World", 
    "World", "World", "World", "World", "World", "World", "World", 
    "World")), .Names = c("Period", "value", "variable"), row.names = c(NA, 
    -13L), class = "data.frame") 

Oto ggplot:

library(ggplot2) 
    p <- ggplot(data = df, aes(x = Period, y = value, group = variable)) + geom_line() + theme_bw() 

Poniższy będzie działać, jeśli miałem miejsca po łączniku:

library(stringr) 
    p + scale_x_discrete(labels = function(x) str_wrap(x, width = 4)) 

[Dwie powyższe linie zostały użyte do wytworzenia drugiego wykresu po ręcznym zmodyfikowaniu parametru datafra mi dodać spację po dniu, oddzielając łącznikiem, innymi słowy, po tym jak oszukał]

następujące podejście do wydrukowania mniej etykiet zazwyczaj działa, ale nie tutaj:

library(scales) 
    p + scale_x_discrete(breaks = pretty_breaks(n = 6)) 

Odpowiedz

6

Czy to co Cię szuka?

p + scale_x_discrete(
    labels=function(x){ 
    x2 <- sub("(\\d+)\\-(\\d+)", 
       "\\1\\-\n\\2", 
       x) 
    x2 
    }) 

enter image description here

Właściwie pośredni x2 nie jest nawet konieczne,

p + scale_x_discrete(
    labels=function(x){ 
    sub("(\\d+)\\-(\\d+)","\\1\\-\n\\2",x) 
    }) 

jest trochę bardziej zwarty.

Edit: Jeszcze rozwiązanie bardziej zwięzłe, dzięki @jlhoward:

p + scale_x_discrete(
    labels=function(x) sub("-","-\n",x,fixed=TRUE)) 
+1

Dzięki @nrussell, w międzyczasie ja zrozumiałem, że mogę używać '' str_replace'' z '' stringr' 'pakiet. Tęskniłem za tym, straciłem czas na '' str_sub'' nie zdając sobie sprawy, że jest tam '' str_replace''. Rozwiązaniem '' stringr'' jest: '' p + scale_x_discrete (labels = function (x) str_wrap (str_replace (x, "-", "-"), width = 4)) '' – PatrickT

+0

Rozwiązanie zgodne z tymi liniami Sugeruję to, czego się spodziewałem, ale po prostu nie wiem, jak działają te backslashe i '' d + '' i przekonałem się, że nigdy bym tego nie wymyślił. I patrząc na termin wewnątrz '' sub() '', jest oczywiste, że nie mogłem wymyślić tego samego! Dzięki, :-) – PatrickT

+1

Nie ma za co; '\\ d +' jest skrótem dla "1 lub więcej kolejnych cyfr" w składni wyrażenia regularnego.Odwrotne ukośniki poprzedzające łącznik mogą lub nie mogły być potrzebne - niektóre symbole regex mają specjalne znaczenie i muszą być unikane (podwójne ucieczki w R i niektórych innych językach) w celu interpretacji dosłownej; Zawsze dokładnie to zapominam, więc robię to z większością symboli, aby być bezpiecznym. '\\ 1' odwołuje się do pierwszej grupy przechwytywania (' (\\ d +) '), a' \\ 2' odwołuje się do drugiej '(\\ d +)'. Zobacz [tutaj] (http://www.rexegg.com/regex-quickstart.html). – nrussell

Powiązane problemy