ファセットラベルを変更する方法


231

次のggplotコマンドを使用しました。

ggplot(survey, aes(x = age)) + stat_bin(aes(n = nrow(h3), y = ..count.. / n), binwidth = 10)
  + scale_y_continuous(formatter = "percent", breaks = c(0, 0.1, 0.2))
  + facet_grid(hospital ~ .)
  + theme(panel.background = theme_blank())

生産する

代替テキスト

私は変更したいファセット(のような短いものに、しかし、ラベルをHosp 1Hosp 2彼らは今、長すぎると見た目が窮屈ので、グラフの高さを高くする(...)オプションではありません、それはにあまりにも多くのスペースを取るだろうドキュメント)。facet_gridのヘルプページを見ましたが、その方法がわかりません。

回答:


124

基礎となる因子レベル名を次のように変更します。

# Using the Iris data
> i <- iris
> levels(i$Species)
[1] "setosa"     "versicolor" "virginica" 
> levels(i$Species) <- c("S", "Ve", "Vi")
> ggplot(i, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)

12
@wishihadabettername:基礎となるデータを変更しないようにするには、使用することができます: ggplot(transform(iris, Species = c("S", "Ve", "Vi")[as.numeric(Species)]), aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)
アルノーA

1
関連...パネルのラベルをbquote()式にしたい場合(例:)levels(x$measurements) <- c(bquote(Area ~~ (cm^2)), bquote(Length ~~ (cm)))、数式には表示されません。式をファセットラベルとしてどのように表示しますか?
ブライアンD

、使用ファセットラベルで式を含むために関連するlabellerオプションにfacet_gridstackoverflow.com/questions/37089052/...
ブライアン・D

285

データの編集を回避するソリューションは次のとおりです。

プロットがgroupレベルを持つデータフレームの一部によってファセット化されているとしたらcontrol, test1, test2、それらの値によって名前が付けられたリストを作成します。

hospital_names <- list(
  'Hospital#1'="Some Hospital",
  'Hospital#2'="Another Hospital",
  'Hospital#3'="Hospital Number 3",
  'Hospital#4'="The Other Hospital"
)

次に 'labeller'関数を作成し、それをfacet_grid呼び出しにプッシュします。

hospital_labeller <- function(variable,value){
  return(hospital_names[value])
}

ggplot(survey,aes(x=age)) + stat_bin(aes(n=nrow(h3),y=..count../n), binwidth=10)
 + facet_grid(hospital ~ ., labeller=hospital_labeller)
 ...

これは、データフレームのレベルを使用して、hospital_namesリストにインデックスを付け、リストの値(正しい名前)を返します。


これは、ファセット変数が1つしかない場合にのみ機能することに注意してください。2つのファセットがある場合、ラベラー関数はファセットごとに異なる名前ベクトルを返す必要があります。あなたは次のようなものでこれを行うことができます:

plot_labeller <- function(variable,value){
  if (variable=='facet1') {
    return(facet1_names[value])
  } else {
    return(facet2_names[value])
  }
}

どこfacet1_namesfacet2_namesファセットインデックス名(「Hostpital#1」など)によってインデックス付けた名前のリストを事前に定義されています。


編集:上記のメソッドは、ラベラーが知らない変数/値の組み合わせを渡すと失敗します。次のような不明な変数のフェイルセーフを追加できます。

plot_labeller <- function(variable,value){
  if (variable=='facet1') {
    return(facet1_names[value])
  } else if (variable=='facet2') {
    return(facet2_names[value])
  } else {
    return(as.character(value))
  }
}

ファセットとmargin = TRUEを使用してggplotでstrip.textラベルを変更する方法からの回答


編集:警告:この方法を使用して文字列のファセットを作成している場合、誤ったラベルが取得される可能性があります。このバグレポートを参照してください。 ggplot2の最近のバージョンで修正されました。


9
いいですが、facet_wrapでは機能しませんが、@ Vinceソリューションではfacet_wrapでも機能します。
Arnaud A

@ArnaudAmzallag:正解ですが、誰かが時間を寄付したいと思った場合、将来的にはそうなる可能性があります
naught101 2014年

不明なファセット変数のフェイルセーフを追加しました。
naught101

16
注意:これはggplot2 v.2では機能しません-ラベラー機能が変更されました。@mbironsの回答が機能しますstackoverflow.com/a/34811062/162832
Andreas

興味深いですが、これは常に機能するわけではありませんが、因子の編集は常に機能します。
PatrickT 2017年

214

@ naught101によって与えられたものの精神にある別の解決策は次のとおりですが、より単純であり、ggplot2の最新バージョンで警告をスローしません。

基本的に、最初に名前付き文字ベクトルを作成します

hospital_names <- c(
                    `Hospital#1` = "Some Hospital",
                    `Hospital#2` = "Another Hospital",
                    `Hospital#3` = "Hospital Number 3",
                    `Hospital#4` = "The Other Hospital"
                    )

そして、@ naught101で指定されたコードの最終行を次のように変更するだけで、それをラベラーとして使用します。

... + facet_grid(hospital ~ ., labeller = as_labeller(hospital_names))

お役に立てれば。


ggplot2のどのバージョンがas_labeller入っていますか?CRANのGitHubリポジトリでいくつかのソースコードを見つけましたが、(CRANで)最新バージョンにアップグレードした後、機能がなくなったようです。
n1k31t4

それは変だ。CRANでも更新しました。ドキュメントdocs.ggplot2.org/dev/as_labeller.html
mbiron

4
これはカッコいい。ファセットグリッドに2つの変数がある場合はどうなりますか?同様hospital ~ genderか何か?両方の軸でラベラーを使用する方法はありますか?ドキュメントに明らかなものは何もありません。
naught101

3
naughtの答えから始めた場合、これはc()でのみ機能し、list()では機能しないことに注意してください。
thomas88wp

1
これの大きな部分は、これがファセットグリッドの両方の軸で機能することです。
カルムあなた

30

これがfacet_grid(yfacet~xfacet)ggplot2、バージョン2.2.1 を使用してそれをどのようにしたかです:

facet_grid(
    yfacet~xfacet,
    labeller = labeller(
        yfacet = c(`0` = "an y label", `1` = "another y label"),
        xfacet = c(`10` = "an x label", `20` = "another x label")
    )
)

これには呼び出しが含まれていないことに注意してくださいas_labeller()-しばらくの間苦労しました。

このアプローチは、ヘルプページCoerce to labeller functionの最後の例から発想を得ています


これは動作します!!! 提案されたソリューションのいくつかは現在のggplot2バージョンで廃止されたため、他のソリューションを適用できませんでした。
ヤンス2017

これらの名前付きベクターは、setNames() stackoverflow.com
a / 22428439/3362993

23

2つのファセットがhospitalありroom、1つだけの名前を変更したい場合は、次を使用できます。

facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))

ベクトルベースのアプローチを使用して2つのファセットの名前を変更するには(naught101の回答のように)、次のようにします。

facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names),
                                                 room = as_labeller(room_names)))

16

基になるデータを変更せずに変更する最も簡単な方法は次のとおりです。

1)各デフォルト値にバックティックマークを追加するas_labeller関数使用してオブジェクトを作成します。

hum.names <- as_labeller(c(`50` = "RH% 50", `60` = "RH% 60",`70` = "RH% 70", `80` = "RH% 80",`90` = "RH% 90", `100` = "RH% 100")) #Necesarry to put RH% into the facet labels

2)GGplotに追加します。

ggplot(dataframe, aes(x=Temperature.C,y=fit))+geom_line()+ facet_wrap(~Humidity.RH., nrow=2,labeller=hum.names)

1
これは最もエレガントな方法だと思います-効果的で、ggplot2バージョン3.0.0.9000で動作します
Landak

9

ggplotが変数に実際に含まれているよりも少ない要素を表示する場合、このソリューションはうまく機能しないことに注意してください(たとえば、サブセット化している場合に発生する可能性があります)。

 library(ggplot2)
 labeli <- function(variable, value){
  names_li <- list("versicolor"="versi", "virginica"="virg")
  return(names_li[value])
 }

 dat <- subset(iris,Species!="setosa")
 ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli)

単純な解決策(面倒な可能性がある、names_liにすべての未使用の要素を追加する以外に)は、元のデータセットまたはlabbeler関数のいずれかで、droplevels()を使用して未使用の要素を削除します。以下を参照してください。

labeli2 <- function(variable, value){
  value <- droplevels(value)
  names_li <- list("versicolor"="versi", "virginica"="virg")
  return(names_li[value])
}

dat <- subset(iris,Species!="setosa")
ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli2)

9

このソリューションは、@ domiのソリューションに非常に似ていますが、最初の4文字と最後の数字をフェッチすることで名前を短くするように設計されています。

library(ggplot2)

# simulate some data
xy <- data.frame(hospital = rep(paste("Hospital #", 1:3, sep = ""), each = 30),
                 value = rnorm(90))

shortener <- function(string) {
  abb <- substr(string, start = 1, stop = 4) # fetch only first 4 strings
  num <- gsub("^.*(\\d{1})$", "\\1", string) # using regular expression, fetch last number
  out <- paste(abb, num) # put everything together
  out
}

ggplot(xy, aes(x = value)) +
  theme_bw() +
  geom_histogram() +
  facet_grid(hospital ~ ., labeller = labeller(hospital = shortener))

ここに画像の説明を入力してください


6

どちらfacet_wrapfacet_gridもからの入力を受け付けるifelse引数として。したがって、ファセットに使用される変数が論理的な場合、解決策は非常に簡単です。

facet_wrap(~ifelse(variable, "Label if true", "Label if false"))

変数にさらにカテゴリがある場合、ifelseステートメントをネストする必要があります。

副作用として、これにより、ggplot通話内でファセットを作成するグループの作成も可能になります。


5

数学記号、上付き文字、下付き文字、括弧/大括弧などを解析する@domiと同様の別のソリューションを追加します。

library(tidyverse)
theme_set(theme_bw(base_size = 18))

### create separate name vectors
# run `demo(plotmath)` for more examples of mathematical annotation in R
am_names <- c(
  `0` = "delta^{15}*N-NO[3]^-{}",
  `1` = "sqrt(x,y)"
)

# use `scriptstyle` to reduce the size of the parentheses &
# `bgroup` to make adding `)` possible 
cyl_names <- c(
  `4` = 'scriptstyle(bgroup("", a, ")"))~T~-~5*"%"',
  `6` = 'scriptstyle(bgroup("", b, ")"))~T~+~10~degree*C',
  `8` = 'scriptstyle(bgroup("", c, ")"))~T~+~30*"%"'
)

ggplot(mtcars, aes(wt, mpg)) + 
  geom_jitter() +
  facet_grid(am ~ cyl,
             labeller = labeller(am  = as_labeller(am_names,  label_parsed),
                                 cyl = as_labeller(cyl_names, label_parsed))
             ) +
  geom_text(x = 4, y = 25, size = 4, nudge_y = 1,
            parse = TRUE, check_overlap = TRUE,
            label = as.character(expression(paste("Log"["10"], bgroup("(", frac("x", "y"), ")")))))

### OR create new variables then assign labels directly
# reverse facet orders just for fun
mtcars <- mtcars %>% 
  mutate(am2  = factor(am,  labels = am_names),
         cyl2 = factor(cyl, labels = rev(cyl_names), levels = rev(attr(cyl_names, "names")))
  )

ggplot(mtcars, aes(wt, mpg)) + 
  geom_jitter() +
  facet_grid(am2 ~ cyl2,
             labeller = label_parsed) +
  annotate("text", x = 4, y = 30, size = 5,
           parse = TRUE, 
           label = as.character(expression(paste("speed [", m * s^{-1}, "]"))))

reprexパッケージ(v0.2.1.9000)によって2019-03-30に作成されました



3

他のすべての解決策がこれを行うのに本当に役立つと思いますが、まだ別の方法があります。

私が想定し:

  • dplyr便利なmutateコマンドが含まれているパッケージをインストールしている。
  • データセットの名前はsurveyです。

    調査%>%mutate(Hosp1 = Hospital1、Hosp2 = Hospital2、........)

このコマンドを使用すると、列の名前を変更できますが、他のすべての列は保持されます。

それから同じfacet_wrapことをしてください、あなたは今大丈夫です。


申し訳ありませんが、列のコンテンツも変更するため機能しません
Jens

3

variable, value引数としてのラベラー関数の定義は、私には機能しません。また、式を使用する場合arr[val]は、関数の引数がdata.frameであるため、lapplyを使用する必要があり、単純にを使用することはできません。

このコードは機能しました:

libary(latex2exp)
library(ggplot2)
arr <- list('virginica'=TeX("x_1"), "versicolor"=TeX("x_2"), "setosa"=TeX("x_3"))
mylabel <- function(val) { return(lapply(val, function(x) arr[x])) }
ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) + geom_line() + facet_wrap(~Species, labeller=mylabel)

3

投稿へのコメントはまだ許可されていないので、Vinceの回答son520804の回答補遺として個別に投稿します。クレジットは彼らに行きます。

Son520804:

アイリスデータの使用:

私は仮定します:
便利なmutateコマンドが含まれているdplyrパッケージをインストールし、データセットの名前はsurveyです。 survey %>% mutate(Hosp1 = Hospital1, Hosp2 = Hospital2,........) このコマンドを使用すると、列の名前を変更できますが、他のすべての列は保持されます。次に、同じfacet_wrapを実行します。これで問題ありません。

Vinceのアイリスの例とson520804の部分コードを使用して、これをmutate関数で実行し、元のデータセットに触れずに簡単な解決策を実現しました。トリックは、スタンドインの名前ベクトルを作成し、パイプ内でmutate()を使用して一時的にファセット名を修正することです。

i <- iris

levels(i$Species)
[1] "setosa"     "versicolor" "virginica"

new_names <- c(
  rep("Bristle-pointed iris", 50), 
  rep("Poison flag iris",50), 
  rep("Virginia iris", 50))

i %>% mutate(Species=new_names) %>% 
ggplot(aes(Petal.Length))+
    stat_bin()+
    facet_grid(Species ~ .)

この例では、i $ Speciesのレベルが、new_namesベクトルに含まれる対応する共通名に一時的に変更されていることがわかります。含む行

mutate(Species=new_names) %>%

簡単に削除して、元の名前を表示できます。

注意: new_nameベクトルが正しく設定されていないと、名前にエラーが発生しやすくなります。変数文字列を置き換えるために別の関数を使用するほうがはるかにクリーンです。元のデータセットの順序と一致させるために、new_nameベクトルをさまざまな方法で繰り返す必要がある場合があることに注意してください。これが正しく行われていることをダブルチェックおよびトリプルチェックしてください。


これは、使用するビットよりよいことがありますnew_names <- c('setosa' = 'Bristle-pointed iris', 'versicolor' = 'Poison flag iris', 'virginica' = 'Virginia iris')し、その後のmutateにあなたはthusly新しい列を作成することができます:mutate(Spec = new_names[Species])
filups21

3

これは私のために働いています。

因子を定義します。

hospitals.factor<- factor( c("H0","H1","H2") )

で使用しggplot()ます:

facet_grid( hospitals.factor[hospital] ~ . )

2

naught101の答えを広げるだけ-クレジットは彼にあります

plot_labeller <- function(variable,value, facetVar1='<name-of-1st-facetting-var>', var1NamesMapping=<pass-list-of-name-mappings-here>, facetVar2='', var2NamesMapping=list() )
{
  #print (variable)
  #print (value)
  if (variable==facetVar1) 
    {
      value <- as.character(value)
      return(var1NamesMapping[value])
    } 
  else if (variable==facetVar2) 
    {
      value <- as.character(value)
      return(var2NamesMapping[value])
    } 
  else 
    {
      return(as.character(value))
    }
}

名前から名前へのマッピングでリストを作成する必要があります

clusteringDistance_names <- list(
  '100'="100",
  '200'="200",
  '300'="300",
  '400'="400",
  '600'="500"
)

plot_labeller()新しいデフォルト引数で再定義します。

plot_labeller <- function(variable,value, facetVar1='clusteringDistance', var1NamesMapping=clusteringDistance_names, facetVar2='', var1NamesMapping=list() )

その後:

ggplot() + 
  facet_grid(clusteringDistance ~ . , labeller=plot_labeller) 

または、必要なラベル変更ごとに専用の関数を作成できます。


2

基礎となるデータを変更せずに同じ目標を達成する別の方法があります。

ggplot(transform(survey, survey = factor(survey,
        labels = c("Hosp 1", "Hosp 2", "Hosp 3", "Hosp 4"))), aes(x = age)) +
  stat_bin(aes(n = nrow(h3),y=..count../n), binwidth = 10) +
  scale_y_continuous(formatter = "percent", breaks = c(0, 0.1, 0.2)) +
  facet_grid(hospital ~ .) +
  opts(panel.background = theme_blank())

上記で行ったのは、元のデータフレームの因子のラベルを変更することです。これが、元のコードとの唯一の違いです。


1

Hospitalベクターの特定のレベルを変更してみましたか?

levels(survey$hospital)[levels(survey$hospital) == "Hospital #1"] <- "Hosp 1"
levels(survey$hospital)[levels(survey$hospital) == "Hospital #2"] <- "Hosp 2"
levels(survey$hospital)[levels(survey$hospital) == "Hospital #3"] <- "Hosp 3"

1

この作業を行うのにかなり時間がかかったので、これに私の答えを追加する必要があると思います。

この答えはあなたのためです:

  • あなたはないではない、あなたの元のデータを編集したいです
  • ラベルにbquote)が必要場合
  • 別のラベリング名ベクトルの柔軟性が必要な場合

基本的にはラベルを名前付きベクターに入れて、ラベルが混乱したり切り替えられたりしないようにします。labeller式は、おそらく単純かもしれないが、これは少なくとも作品で(改善は非常に歓迎されています)。ファセットファクターを保護するための `(バッククォート)に注意してください。

n <- 10
x <- seq(0, 300, length.out = n)

# I have my data in a "long" format
my_data <- data.frame(
  Type = as.factor(c(rep('dl/l', n), rep('alpha', n))),
  T = c(x, x),
  Value = c(x*0.1, sqrt(x))
)

# the label names as a named vector
type_names <- c(
  `nonsense` = "this is just here because it looks good",
  `dl/l` = Linear~Expansion~~Delta*L/L[Ref]~"="~"[%]", # bquote expression
  `alpha` = Linear~Expansion~Coefficient~~alpha~"="~"[1/K]"
  )


ggplot() + 
  geom_point(data = my_data, mapping = aes(T, Value)) + 
  facet_wrap(. ~ Type, scales="free_y", 
             labeller = label_bquote(.(as.expression(
               eval(parse(text = paste0('type_names', '$`', Type, '`')))
               )))) +
  labs(x="Temperature [K]", y="", colour = "") +
  theme(legend.position = 'none')

ここに画像の説明を入力してください


1

簡単な解決策(ここから):

p <- ggplot(mtcars, aes(disp, drat)) + geom_point()
# Example (old labels)
p + facet_wrap(~am)


to_string <- as_labeller(c(`0` = "Zero", `1` = "One"))
# Example (New labels)
p + facet_wrap(~am, labeller = to_string)

0

しばらく苦労した後、私が見つけた私たちが使用できることであるfct_relevel()fct_recode()から、forcatsファセットの順序を変更するだけでなく、ファセットラベルを修正するために一緒に。それが設計でサポートされているかどうかはわかりませんが、動作します!以下のプロットをチェックしてください:

library(tidyverse)

before <- mpg %>%
  ggplot(aes(displ, hwy)) + 
  geom_point() +
  facet_wrap(~class)
before

after <- mpg %>%
  ggplot(aes(displ, hwy)) + 
  geom_point() + 
  facet_wrap(
    vars(
      # Change factor level name
      fct_recode(class, "motorbike" = "2seater") %>% 
        # Change factor level order
        fct_relevel("compact")
    )
  )
after

2020-02-16にreprexパッケージ(v0.3.0)によって作成されました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.