47

aesggplotでプロットするときに、でローカル変数を使用しようとしています。これが私の問題です。

xy <- data.frame(x=1:10,y=1:10)

plotfunc <- function(Data,YMul=2){
    ggplot(Data,aes(x=x,y=y*YMul))+geom_line()
}

plotfunc(xy)

これにより、次のエラーが発生します。

Error in eval(expr, envir, enclos) : object 'YMul' not found

でローカル変数(または関数の引数)を使用できないようですaesaes後でローカル変数がスコープ外になったときに実行される内容が原因で発生する可能性がありますか?どうすればこの問題を回避できますか(内でローカル変数を使用しない場合を除くaes)?

4

6 に答える 6

39

ローカル環境をキャプチャし、

xy <- data.frame(x=1:10,y=1:10)

plotfunc <- function(Data, YMul = 2){
    .e <- environment()
    ggplot(Data, aes(x = x, y = y*YMul), environment = .e) + geom_line()
}

plotfunc(xy)
于 2012-05-19T06:33:06.520 に答える
10

data.frame またはグローバル環境に値YMulを追加することなく、引数を介して任意の値を渡すことができる代替手段を次に示します。Data

plotfunc <- function(Data, YMul = 2){
    eval(substitute(
        expr = {
            ggplot(Data,aes(x=x,y=y*YMul)) + geom_line()
        }, 
        env = list(YMul=YMul)))
    }

plotfunc(xy, YMul=100)

これがどのように機能するかを確認するには、次の行を単独で試してください。

substitute({ggplot(Data, aes(x=x, y=y*YMul))}, list(YMul=100))
于 2012-05-18T20:50:13.753 に答える
5

ggplot()は、データフレーム内の変数であるとaes想定しています。代わりにそこに含めてみてください:YMuldataYMull

@Justinのおかげで:ggplot()'saesは最初にデータフレームで検索しYMuldata見つからない場合はグローバル環境で検索するようです。概念的には理にかなっているので、次のように、このような変数をデータフレームに追加するのが好きです。また、関数に予期しない結果をもたらすグローバル変数の変更について心配する必要はありません。しかし、他のすべての答えも正しいです。だから、あなたに合ったものを使ってください。

require("ggplot2")
xy <- data.frame(x = 1:10, y = 1:10)
xy <- cbind(xy, YMul = 2)

ggplot(xy, aes(x = x, y = y * YMul)) + geom_line()

または、例の関数が必要な場合:

plotfunc <- function(Data, YMul = 2)
{
    ggplot(cbind(Data, YMul), aes(x = x, y = y * YMul)) + geom_line()
}

plotfunc(xy)
于 2012-05-18T20:35:36.327 に答える
4

私はggplot2を使用していますが、あなたの例は現在のバージョンでうまくいくようです。

ただし、依然として問題を引き起こす亜種を考え出すのは簡単です。私自身も同様の動作に混乱していましたが、それがこの投稿を見つけた方法です(「渡されたときに変数を評価する方法をggplotする方法」のGoogleのトップ結果)。たとえば、ggplot を plotfunc から移動すると、次のようになります。

xy <- data.frame(x=1:10,y=1:10)

plotfunc <- function(Data,YMul=2){
  geom_line(aes(x=x,y=y*YMul))
}

ggplot(xy)+plotfunc(xy)
# Error in eval(expr, envir, enclos) : object 'YMul' not found

上記のバリアントでは、ggplot は関数内から呼び出されず、ggplot のみが「environment=」引数を持つため、「ローカル環境のキャプチャ」は解決策ではありません。

しかし、「aes」に似ていますが、ローカル変数をキャプチャする関数「aes_」、「aes_string」、「aes_q」のファミリがあります。上記で「aes_」を使用すると、「x」を認識しないため、エラーが発生します。しかし、データを直接参照するのは簡単で、問題を解決します:

plotfunc <- function(Data,YMul=2){
  geom_line(aes_(x=Data$x,y=Data$y*YMul))
}
ggplot(xy)+plotfunc(xy)
# works
于 2016-03-07T19:39:03.653 に答える
0

関数の外でコードを実行すると、機能します。YMulそして、グローバルに定義された関数内でコードを実行すると、機能します。内部の仕組みを完全には理解していませんggplotが、これは機能します...

YMul <- 2

plotfunc <- function(Data){
    ggplot(Data,aes(x=x,y=y*YMul))+geom_line()
}

plotfunc(xy)
于 2012-05-18T20:39:53.070 に答える