変数を使用してggplotで列名を指定する方法


105

ggplotコマンドがあります

ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )

関数内。ただし、関数のパラメーターを使用して、色とグループとして使用する列を選択できるようにしたいと思います。つまり、私はこのようなものを望みます

f <- function( column ) {
    ...
    ggplot( rates.by.groups, aes(x=name, y=rate, colour= ??? , group=??? ) )
}

そのため、ggplotで使用される列はパラメーターによって決定されます。たとえば、f( "majr")の場合、次の効果が得られます。

ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )

しかし、f( "gender")の場合、

  ggplot( rates.by.groups, aes(x=name, y=rate, colour=gender, group=gender) )

私が試したいくつかのこと:

ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ) )

動作しませんでした。しなかった

e <- environment() 
ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ), environment=e )

回答:


160

使用できますaes_string

f <- function( column ) {
    ...
    ggplot( rates.by.groups, aes_string(x="name", y="rate", colour= column,
                                        group=column ) )
}

列を(f("majr")ではなくf(majr))文字列として関数に渡す限り。また、我々は他の列を変更することに注意してください、"name"そして"rate"、文字列であることを。

何らかの理由でを使用aes_stringしたくない場合は、次のように変更できます(やや面倒です)。

    ggplot( rates.by.groups, aes(x=name, y=rate, colour= get(column),
                                        group=get(column) ) )

あなたがすべきでない/できないことaes_string(x = rates.by.groups$name...、そしてとにかくあなたはすでにggplot(data = rates.by.groups...引数を渡したのであなたがする必要はないということは価値があります。(この質問の問題
smci

3
ggplot2バージョン3.0.0の更新を使用して、Moody_Mudskipperの回答を説明するメモを追加するだけ
グレゴールトーマス

@buncisそれは真実ではない、引用する"column_name"か、"column"うまくいかない
デビッド・ロビンソン

@DavidRobinson申し訳ありませんが、コードがパラメーター付きの関数にラップされているのがわかりません。コメントを削除します
buncis

「面倒」?Rの非標準評価は、皮肉にも私がプログラミング言語で遭遇し​​た最も厄介な「機能」です。本当に狂ってる。
jessexknight

43

リリースノートからggplot2 V3.0.0

aes()が準引用をサポートするようになったため、!!、!!!、および:=を使用できます。これは、現在は非推奨となっているaes_()とaes_string()に代わるものです(ただし、長期間にわたって使用されます)。

慣用的な方法は、変数に含まれる文字列をシンボルに変換してsym()(基本エイリアスas.name()/ とほとんど同じですas.symbol())、引用符を外して!!

私たちができるOPのデータのシミュレーション:

library(tidyverse)
rates.by.groups <- data.frame(
  name = LETTERS[1:3],
  rate = 1:3,
  mjr = LETTERS[c(4,4,5)],
  gender = c("M","F","F")
)

f <- function(column) {
  column <- sym(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

f("gender")
f("mjr")
x <- "gender"
f(x)

生の名前を関数にフィードする場合は、次のようにします。

f2 <- function(column) {
  column <- ensym(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

名前またはシンボルと文字列リテラルで動作します

f2(gender)
f2(mjr)
f2("gender")
f2("mjr")

ライオネルが言うようにensym()

これは、LHSで両方を指定できる引数の構文を模倣することを意味します。例:list(bare = 1、 "quoted" = 2)


についてのメモ enquo()

enquo()引数に与えられた式(必ずしも記号ではない)を引用符で囲みます。文字列リテラルは記号のように変換されensym()ないため、ここではあまり適応されない可能性がありますが、次のようにできます。

f3 <- function(column) {
  column <- enquo(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

f3(gender)
f2(mjr)

12
このチディヴァルのものはとても迷惑です。ドキュメンテーションaes()自体について説明していますenquo()が、機能しません。そして、ensym()以前に聞いた人は誰ですか?BIG SIGH
CoderGuy123

@Moody_Mudskipper f2では、4つの例はすべて機能し、列名を変数(つまりaname <- "mjr"; f2(aname))にキャプチャします。使用しdplyrてデータフレームを操作するコードを追加すると、変数名の文字列ではなく、変数名を使用して列が検索されます。言い換えれば、どのように私はrates.by.groups %>% group_by(!!column)...働き、3つの呼び出し方法をサポートしますf2か?
steveb

1
「そうすることで、変数内の列名をキャプチャします」:失敗することはありませんが、同じ結果を返しませんensym。名前として提供された引数を処理し、それらを囲む引用符を許容するように設計されています。引数を名前として扱い、名前が見つからない場合は値にフォールバックしたいと思います。これは実際にはで発生しますがselect、では発生しませんgroup_by...ハッキングすることは可能ですが、明白ではありません。それがあなたにとって重要であるなら、私はそれがそれ自身の質問に値するだろうと思います。
Moody_Mudskipper

@Moody_Mudskipperありがとう。私は両方selectを使用していたgroup_byので、おそらくそれが問題でした。新しい質問を作成できますが、簡単な例を考えて、それが回答されているかどうかを確認する必要があります。そうでない場合は投稿できます。
steveb

使い方 !!の場合facet_grid?動作しますfacet_grid(cols = vars(!!column))が、エラーが発生しますfacet_grid(~ !!column)
mRiddle

14

aes_string代わりに使用してみてくださいaes


5
これは素晴らしいアドバイスですが、理由を教えてもらえますか?aes_stringを使用すると、非変数に ""を使用し、変数を引用符で囲まずに使用できます。aes_string(x = "foo"、y = "fee"、group = variable)
mtelesha

@mtelesha多分変数がその値として文字列を持っているためかもしれません
buncis

9

別のオプション(ggplot2 > 3.0.0)は、整頓された評価代名詞を使用して.datarates.by.groupsデータフレームから選択された変数/列をスライスすることです。

library(ggplot2)
theme_set(theme_classic(base_size = 14))

# created by @Moody_Mudskipper
rates.by.groups <- data.frame(
  name = LETTERS[1:3],
  rate = 1:3,
  mjr = LETTERS[c(4, 4, 5)],
  gender = c("M", "F", "F")
)

f1 <- function(df, column) {
  gg <- ggplot(df, 
         aes(x = name, 
             y = rate, 
             fill  = .data[[column]], 
             group = .data[[column]])) +
    geom_col() +
    labs(fill = column)
  return(gg)
}

plot_list <- lapply(list("gender", "mjr"), function(x){ f1(rates.by.groups, x) })
plot_list
#> [[1]]

#> 
#> [[2]]

# combine all plots
library(egg)
ggarrange(plots = plot_list,
          nrow = 2,
          labels = c('A)', 'B)'))

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


0

を使用aes_stringするとこの問題は解決しますが、エラーバーを追加すると問題が発生しますgeom_errorbar。以下は簡単な解決策です。

#Identify your variables using the names of your columns indie your dataset
 xaxis   <- "Independent"   
 yaxis   <- "Dependent"
 sd      <- "error"

#Specify error bar range (in 'a-b' not 'a'-'b')
 range   <- c(yaxis, sd)                                #using c(X, y) allows use of quotation marks inside formula
 yerrbar <- aes_string(ymin=paste(range, collapse='-'), 
                       ymax=paste(range, collapse='+'))


#Build the plot
  ggplot(data=Dataset, aes_string(x=xaxis, y=yaxis)) +
    geom_errorbar(mapping=yerrbar, width=15, colour="#73777a", size = 0.5) +
    geom_point   (shape=21)

おまけ、ggplot内の次の行を使用して、プロットにファセットを追加することもできます。

facet_grid(formula(paste(Variable1, "~", Variable2)))

このスクリプトは、この元の投稿から変更されました:ggplot2-カスタム関数を使用したエラーバー


0

これは非常に単純な例です。

2つのことを行うだけ

  1. 文字列をシンボルに変える
  2. !!使用時に追加
select_col <- sym("Petal.Length")

iris %>% 
  ggplot(aes(x = Sepal.Length, y = !!select_col)) +
  geom_point()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.