【发布时间】:2020-04-23 06:41:04
【问题描述】:
我正在编写一个函数来从给定的 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 年 4 月 23 日创建
因此,我倾向于使用call,但我想确保这样做不会产生任何意外后果,而不是使用其他解决方案。换句话说,在什么情况下(在我使用它们的上下文中)这四种方法会给出不同的答案,从而导致其中一种方法优于其他方法?
【问题讨论】: