패싯 레이블을 변경하는 방법은 무엇입니까?


230

다음 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 1, Hosp 2그들은 너무 오래 지금과 모습 그래프의 높이를 증가 (비좁은 때문에 ...) 옵션을 선택하지 않습니다, 그것은 너무 많은 공간을 차지 것 문서). 나는 보았다 facet_grid 도움말 페이지하지만 어떻게 알아낼 수 없습니다.

답변:


123

기본 요인 수준 이름을 다음과 같이 변경하십시오.

# 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 ~ .)
Arnaud A

1
related ... 패널 레이블을 bquote () 표현식 (예 :) levels(x$measurements) <- c(bquote(Area ~~ (cm^2)), bquote(Length ~~ (cm)))으로하려면 수학 표현식에 표시되지 않습니다. 표현식을 패싯 레이블로 어떻게 표시합니까?
Brian D

를 사용 패싯 라벨에 표현 등을 위해 관련 labeller옵션 facet_grid: stackoverflow.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 목록을 색인화하고 목록 값 (올바른 이름)을 리턴합니다.


패싯 변수가 하나만있는 경우에만 작동합니다. 패싯이 두 개인 경우 레이 블러 함수는 각 패싯에 대해 다른 이름 벡터를 리턴해야합니다. 다음과 같은 방법 으로이 작업을 수행 할 수 있습니다.

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

패싯 및 여백 = TRUE로 ggplot에서 strip.text 레이블을 변경하는 방법에서 수정 된 답변


편집 : 경고 :이 방법을 사용하여 문자 열에 의해 패싯 인 경우 잘못된 레이블이 표시 될 수 있습니다. 이 버그 리포트를 참조하십시오 . ggplot2의 최신 버전에서 수정되었습니다.


9
멋지지만 facet_wrap에서는 작동하지 않지만 @Vince 솔루션은 facet_wrap에서도 작동합니다.
Arnaud A

@ArnaudAmzallag : 맞습니다. 누군가가 시간을 내주고 싶은 마음이 있다면 , 앞으로는 가능할 것 입니다.
naught101

알 수없는 패싯 변수에 대한 안전 장치를 추가했습니다.
naught101

16
주의 : 이것은 ggplot2 v.2에서 작동하지 않습니다 – 라벨러 기능이 변경되었습니다. @mbirons answer works stackoverflow.com/a/34811062/162832
Andreas

흥미롭지 만 항상 효과가있는 것은 아니지만 요소를 편집하면 항상 효과가 있습니다.
PatrickT

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
이것은 멋지다. 패싯 그리드에 두 개의 변수가 있으면 어떻게됩니까? 좋아하는 hospital ~ gender것? 두 축 모두에서 라벨러를 사용하는 방법이 있습니까? 문서에서 분명한 것을 볼 수 없습니다.
naught101

3
Naught의 답변으로 시작한 경우 list ()가 아닌 c () 에서만 작동합니다 .
thomas88wp

1
이것의 큰 장점 중 하나는 패싯 그리드의 두 축 모두에서 작동한다는 것입니다!
Calum You

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 기능 의 마지막 예에서 영감을 얻었습니다 .


이 작동합니다 !!! 제안 된 솔루션 중 일부가 현재 ggplot2 버전에서 더 이상 사용되지 않기 때문에 다른 솔루션을 적용 할 수 없었습니다.
yanes

이러한 명명 된 벡터를 setNames() stackoverflow.com/a/22428439/3362993을 사용
jsta

23

두 측면이있는 경우 hospitalroom하지만, 단 하나의 이름을 바꾸려면, 당신은 사용할 수 있습니다 :

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

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의 답변에 대한 부록으로 별도로 게시 하고 있습니다. 신용은 그들에게 간다.

아들 520804 :

홍채 데이터 사용 :

: 나는 가정
당신은 편리 개의 mutate 명령이있는 dplyr 패키지를 설치하고 데이터 세트는 설문 조사 지정됩니다. 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에서 다음과 같이 새 열을 만들 수 있습니다.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

reprex 패키지 (v0.3.0)로 2020-02-16에 작성

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.