いくつかの関数に変数を渡そうとしてスタックし、最後の関数で元の変数の名前を取得したいと思います。しかし、Rの代替関数は、「ローカル」環境でのみ、または1つ上のレベルでのみ検索されたようです。さて、コードで説明しましょう:
fun1 <- function (some_variable) {deparse(substitute(some_variable)}
fun2 <- function (var_pass) { fun1 (var_pass) }
my_var <- c(1,2) # I want to get 'my_var' in the end
fun2 (my_var) # > "var_pass"
さて、fun1にのみ渡される変数の名前を出力しているようです。代替のドキュメントは、env引数を使用してどこを探すことができるかを指定できることを示しています。しかし、。Globalまたは。BaseNamespaceEnvを引数として渡すことで、さらに奇妙な結果が得られました-"some_variable"
答えはenv引数を使用したこの関数にあると思います。それで、それがどのように機能し、どのように必要なものを取得できるかを説明してください。前もって感謝します!
これらの関数にオプションの名前の値を渡すことを検討することをお勧めします。これは、最終結果で名前を何かのラベルとして使用したいように思われるためです。そのため、名前ほど重要なのは変数自体ではありません。あなたができる
fun1 <- function (some_variable, name=deparse(substitute(some_variable))) {
name
}
fun2 <- function (var_pass, name=deparse(substitute(var_pass))) {
fun1 (var_pass, name)
}
my_var <- c(1,2)
fun2(my_var)
# [1] "my_var"
fun1(my_var)
# [1] "my_var"
このようにして、奇妙な変数名と結果に適切な名前を付けることになった場合、少なくともオプションがあります。また、デフォルトでは、nameパラメーターを必要とせずに必要な処理を実行する必要があります。
1つのハック、おそらく最善の方法ではありません:
fun2 <- function (var_pass) { fun1 (deparse(substitute(var_pass))) }
fun1 <- function (some_variable) {(some_variable))}
fun2(my_var)
# "my_var"
そして、その上でget
を実行できます。しかし、Paul Hが示唆しているように、変数を追跡するためのより良い方法があります。
私が提案したいもう1つのアプローチは、rlang::enexpr
を使用することです。主な利点は、元の変数名をパラメーターに含める必要がないことです。欠点は、使用するのが少し難しい式を処理する必要があることです。
> fun1 <- function (some_variable) {
message("Entering fun1")
rlang::enexpr(some_variable)
}
> fun2 <- function (var_pass) {
message("Entering fun2")
eval(parse(text=paste0("fun1(", rlang::enexpr(var_pass), ")")))
}
> my_var <- c(1, 2)
> fun1(my_var)
#Entering fun1
my_var
> fun2(my_var)
#Entering fun2
#Entering fun1
my_var
ここでの秘訣は、fun2
の引数名を評価し、fun1
への呼び出しをcharacter
としてビルドする必要があることです。 enexpr(var_pass)
を使用してfun1
を呼び出すだけの場合、enexpr(var_pass)
はfun2
で評価されないため、fun2
の変数名の概念が失われます。
> bad_fun2 <- function (var_pass) {
message("Entering bad fun2")
fun1(rlang::enexpr(var_pass))
}
> bad_fun2(my_var)
#Entering bad fun2
#Entering fun1
rlang::enexpr(var_pass)
その上、fun1
もfun2
も変数名を文字ベクトルとして返さないことに注意してください。返されるオブジェクトはクラスname
です(もちろん、character
に強制変換することもできます)。明るい面は、eval
を直接使用できることです。
> ret <- fun2(my_var)
#Entering fun2
#Entering fun1
> as.character(ret)
[1] "my_var"
> class(ret)
[1] "name"
> eval(ret)
[1] 1 2