Я пишу функцию для извлечения переменной, представленной в виде строки, из заданного 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
Создано в 2020-04-23 пакетом представитель (v0.3.0)
Поэтому я склонен использовать call
, но я хочу убедиться, что не будет никаких непреднамеренных последствий этого, вместо использования других решений. Другими словами, в каких ситуациях (в контексте, в котором я их использую) четыре метода не дают один и тот же ответ, приводя один к предпочтению одного над другими?