我正在编写一个函数以从给定的data.frame df
或环境env
中提取以字符串形式提供的变量。最初,我一直使用eval(parse(text=s), df, env)
构造执行此操作,但是我了解到有更有效的替代方法。其他选项包括:
eval(str2lang(s), df, env)
eval(str2expression(s), df, env)
eval(call(s)[[1]], df, env)
也可能有get
解决方案,但我不知道它是否可以先检查变量是否在df
中,然后再转到env
。
使用microbenchmark
,看来call
是最快的:
library(microbenchmark) x1 = 1 df = data.frame(x2 = 2) microbenchmark(call = eval(call('x1')[[1]], df), parse = eval(parse(text='x1'), df), str2lang = eval(str2lang('x1'), df), str2exp = eval(str2expression('x1'), df), check = "identical") #> Unit: microseconds #> expr min lq mean median uq max neval cld #> call 1.128 1.2115 1.60815 1.4585 1.6360 4.659 100 a #> parse 39.183 39.8705 46.60755 40.2405 42.0415 135.462 100 b #> str2lang 2.235 2.3570 3.26144 2.5995 2.8925 24.641 100 a #> str2exp 2.230 2.3200 2.81387 2.4780 2.6970 10.312 100 a microbenchmark(call = eval(call('x2')[[1]], df), parse = eval(parse(text='x2'), df), str2lang = eval(str2lang('x2'), df), str2exp = eval(str2expression('x2'), df), check = "identical") #> Unit: microseconds #> expr min lq mean median uq max neval cld #> call 1.124 1.194 1.47770 1.3675 1.5795 9.031 100 a #> parse 38.254 38.762 40.21497 38.9630 39.3120 116.510 100 b #> str2lang 2.214 2.304 2.55036 2.3960 2.6530 10.639 100 a #> str2exp 2.238 2.331 2.50011 2.4210 2.6515 3.619 100 a
由reprex package(v0.3.0)在2020-04-23创建
因此,我倾向于使用call
,但我想确保这样做而不是使用其他解决方案不会有任何意外的后果。换句话说,在什么情况下(在我正在使用它们的上下文中),这四种方法将不会给出相同的答案,从而导致一种方法优于另一种方法?
我正在编写一个函数来从给定的data.frame df或环境env中提取以字符串形式提供的变量。最初,我一直在将eval(parse(text = s),df,env)构造用于...
我认为这取决于您要评估的字符串。如果它始终是一个名字,那么as.name('x1')
可能也是一个竞争者。我的测试表明,该方法比使用call
的解决方案要慢一点,但是我想说它是更好的选择,因为它不那么晦涩难懂,并且不太可能引起将来的头痛。