gpt4 book ai didi

r - R 中干净、简单的函数工厂

转载 作者:行者123 更新时间:2023-12-04 12:11:47 26 4
gpt4 key购买 nike

简短的例子。 我正在通过使用不同的“规范”对其进行测试来探索函数的行为,f(spec) .我手写了一个规范,spec1 ,并且正在创建新规范作为其变体。为此,我决定编写一个函数:

spec1 = list(fy = list(a = 1), fx = list(f1 = function(x) 10-x, f2 = function(x) 2-x))

make_spec = function(f = function(x) 10-x, xtheta = 2)
list(fy = list(a = 1), fx = list(f1 = f, f2 = function(x) xtheta-x))

res1 = make_spec()

# first problem: they don't match

all.equal(res1,spec1)
# [1] "Component “fx”: Component “f2”: target, current do not match when deparsed"
# ^ this happens, even though...
res1$fx$f2(4) == spec1$fx$f2(4)
# TRUE

# second problem: res1 is fugly

res1
# $fy
# $fy$a
# [1] 1
#
#
# $fx
# $fx$f1
# function (x)
# 10 - x
# <environment: 0x000000000f8f2e20>
#
# $fx$f2
# function (x)
# xtheta - x
# <environment: 0x000000000f8f2e20>

str(res1)
# even worse

我的目标 make_spec是...
  • all.equal(spec1, res1)和/或 identical(spec1, res1)
  • str(res1)是人类可读的(没有 <environment: ptr> 标签或 srcfilecopy)
  • 避免 substituteeval如果可能的话(不是高优先级)
  • 避免写出 substitute 的第二个参数(参见下面的“完整”示例)

  • 是否有一种惯用的方法来实现部分或所有这些目标?

    完整的例子。 我不确定上面的例子是否完全涵盖了我的用例,所以这里是后者:
    spec0 = list(
    v_dist = list(
    pdf = function(x) 1,
    cdf = function(x) x,
    q = function(x) x,
    supp = c(0,1)
    )
    ,
    ucondv_dist = {
    ucondv_dist = list()
    ucondv_dist$condmean = function(v) 10-v
    ucondv_dist$pdf = function(u,v) dnorm(u, ucondv_dist$condmean(v), 50)
    ucondv_dist$cdf = function(u,v) pnorm(u, ucondv_dist$condmean(v), 50)
    ucondv_dist
    }
    )

    make_spec = function(ycondx_condmean = function(x) 10-x, ycondx_sd = 50){

    s = substitute(list(
    x_dist = list(
    pdf = function(x) 1,
    cdf = function(x) x,
    q = function(x) x,
    supp = c(0,1)
    )
    ,
    ycondx_dist = {
    ycondx_dist = list()
    ycondx_dist$condmean = ycondx_condmean
    ycondx_dist$pdf = function(u,v) dnorm(u, ycondx_dist$condmean(v), ycondx_sd)
    ycondx_dist$cdf = function(u,v) pnorm(u, ycondx_dist$condmean(v), ycondx_sd)
    ycondx_dist
    }
    )
    , list(ycondx_condmean=ycondx_condmean, ycondx_sd = ycondx_sd))

    eval(s, .GlobalEnv)
    }

    res0 = make_spec()

    旁注 .我不知道“函数工厂”在这里是否合适,因为我不是计算机科学家,但它似乎相关。我只找到了 a paragraph on the concept related to R .

    最佳答案

    函数的封闭环境不同导致输出的差异/解析的差异。因此,要获得所需的输出,需要做两件事:

  • 使环境相同
  • 将封闭环境中的变量替换到函数体中。

  • 然而,这样做你会得到你不想要的双倍剂量的评估/替代品,所以也许会有另一种选择。
    make_spec <- function(f = function(x) 10-x, xtheta = 2) {
    e <- parent.frame()
    fixClosure <- function(func)
    eval(eval(substitute(substitute(func)), parent.frame()), e)

    list(fy = list(a = 1), fx = list(
    f1 = fixClosure(f),
    f2 = fixClosure(function(x) xtheta-x)
    ))
    }

    spec1 <- list(fy = list(a = 1), fx = list(f1 = function(x) 10-x, f2 = function(x) 2-x))
    res1 <- make_spec()

    all.equal(res1, spec1)
    [1] TRUE

    关于r - R 中干净、简单的函数工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36162948/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com