web-dev-qa-db-ja.com

Rの関数に変数名を渡す

かなりの数のパッケージを使用すると、関数が呼び出されるコンテキストでは有効ではないシンボル名を渡すことができることに気付きました。これがどのように機能し、自分のコードでどのように使用できるのか疑問に思っていますか?

Ggplot2の例を次に示します。

a <- data.frame(x=1:10,y=1:10)
library(ggplot2)
qplot(data=a,x=x,y=y)

xyは私の名前空間に存在しませんが、ggplotはそれらがデータフレームの一部であることを理解し、有効なコンテキストへの評価を延期します。私は同じことをやってみました:

b <- function(data,name) { within(data,print(name)) }
b(a,x)

ただし、これは惨めに失敗します。

Error in print(name) : object 'x' not found

私は何を間違えていますか?これはどのように作動しますか?

:これはnotパス変数の複製r =の関数の名前

27
static_rtti

私はこれが古いスレッドであることを知っていますが、私が過去に言及したものです。私は最近、変数名を渡すためのより良いアプローチだと思うものを発見しました。だから私はそれを含めると思った。これが誰かの助けになることを願っています。

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

b <- function(df, name){
    eval(substitute(name), df)
}

b(a, x)
  [1]  1  2  3  4  5  6  7  8  9 10

Updateこのアプローチでは、非標準の評価を使用します。私は説明を始めましたが、ハドリー・ウィッカムが私よりもはるかに優れていることにすぐに気付きました。これを読む http://adv-r.had.co.nz/Computing-on-the-language.html

25
Jacob H

たとえば、_match.call_を使用してこれを行うことができます。

_b <-  function(data,name) {

  ## match.call return a call containing the specified arguments 
  ## and the function name also 
  ## I convert it to a list , from which I remove the first element(-1)
  ## which is the function name

  pars <- as.list(match.call()[-1])
  data[,as.character(pars$name)]

}

 b(mtcars,cyl)
 [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
_

説明:

match.callは、指定されたすべての引数がフルネームで指定されている呼び出しを返します。

したがって、ここで_match.call_の出力は2シンボルです:

_b <-  function(data,name) {
  str(as.list(match.call()[-1]))  ## I am using str to get the type and name
}

b(mtcars,cyl)
List of 2
 $ data: symbol mtcars
 $ name: symbol cyl
_

そこで、最初のシンボルmtcarsと2番目の文字列を文字列に変換するシンボルを使用します。

_mtcars[,"cyl"]
_

またはと同等:

_eval(pars$data)[,as.character(pars$name)]
_
13
agstudy

変数名を引用符で囲む関数を呼び出すときに、それは機能します:

> b <- function(data,name) { within(data,print(name)) }
> b(a, "x")
[1] "x"
    x  y
1   1  1
2   2  2
3   3  3
4   4  4
5   5  5
6   6  6
7   7  7
8   8  8
9   9  9
10 10 10
3
Waldir Leoncio