R用类字符串评估函数

时间:2018-04-23 19:02:30

标签: r string function

我有一个字符串格式Blob的函数我想评估,但我需要先对字符串进行更改。我如何随后从字符格式运行该函数?

"dnorm(0,1)"

上下文: (我正在创建一个函数,我从一个r对象中提取类似于" dnorm"的分布,需要相应的" rnorm()"。解决方案也适用于" dbinom"," dpois"等。)

编辑:添加了str_replace行

2 个答案:

答案 0 :(得分:4)

我认为您需要eval(parse(text=...))gsub(pattern, new_pattern, ...)

的组合
S <- "dnorm(0,1)"
set.seed(1)
eval(parse(text=S))
# 0.2419707
set.seed(1)
T <- gsub("norm", "pois", S)
eval(parse(text=T))
# 0.3678794

答案 1 :(得分:2)

我实际上是parse(text = ...)的粉丝。

例如,如果您有一些命名参数:

old <- 'dnorm(x = 5, mean=1)'
cl <- parse(text = old)[[1L]]
eval(cl)
# [1] 0.0001338302

cl[[1L]] <- dlnorm
eval(cl)
# [1] 0.06626564

cl$mean <- 5
eval(cl)
# [1] 0.0002544689

但在您的情况下,我们可以避免使用parse(text = ...)do.call call,因为未命名的参数可以按位置传递:

old <- 'dnorm(0, 1)'
new <- 'rnorm'


args <- strsplit(old, '[(),]')[[1L]]
args <- lapply(args, type.convert, as.is = TRUE)

do.call(args[[1L]], args[-1L])
# [1] 0.2419707

## add more arguments like n for rnorm
set.seed(1L)
do.call(new, c(5L, args[-1L]))
# [1] -0.6264538  0.1836433 -0.8356286  1.5952808  0.3295078

## or use a named list to pass to a specific argument
# do.call(new, c(n = 5L, args[-1L]))

## or change to another function with similar use
args[[1L]] <- 'pnorm'
cl <- do.call(call, args)
eval(cl)
# [1] 0.1586553    

cl[[1L]] <- pnorm
eval(cl)
# [1] 0.1586553

从统计数据来看,有近400个命运,其中只有2个是反 - parse(text)。那很不错..