【问题标题】:Create multiple functions/varying arguments in R using a list使用列表在 R 中创建多个函数/不同的参数
【发布时间】:2019-11-21 11:08:43
【问题描述】:

我正在尝试创建具有不同参数的多个函数。

只是一些背景知识:我需要分别计算描述 75 天的函数,然后将它们相乘以创建一个最大似然函数。它们都具有相同的形式,它们仅在某些论点上有所不同。这就是为什么我想通过循环来做到这一点。

我尝试将所有方程式放在一个列表中,以便以后访问它们。 此循环生成的列表有 75 个参数,但它们都是相同的,因为循环不考虑定义函数中的 [i],这意味着 M_b[i](具有 75 个参数的向量)确实不变。

有人知道,为什么会这样吗?

使用的简化方程

for (i in 1:75){
  log_likelihood[[i]] <- 
list(function(e_b,mu_b){M_b[i]*log(e_b*mu_b))})
}

我无法在不同的问题中找到答案。对不起,如果已经存在类似的线程。

【问题讨论】:

    标签: r list function for-loop


    【解决方案1】:

    您需要强制评估变量 M_b[i],请参阅https://adv-r.hadley.nz/function-factories.html。下面我试着让它工作

    func = function(i){
        i = force(i)
        f = function(e_b,mu_b){i*log(e_b*mu_b) }
        return(f)
    }
    
    # test
    func(9)(7,3) == 9*log(7*3)
    
    
    #some simulated values for M_b
    M_b = runif(75)
    log_likelihood = vector("list",75)
    
    for (idx in 1:75){
      log_likelihood[[idx]] <- func(M_b[idx])
    }
    # we test it on say e_b=5, mu_b=6
    test = sapply(log_likelihood,function(i)i(5,6))
    actual = sapply(M_b,function(i)i*log(5*6))
    identical(test,actual)
    [1] TRUE
    

    这称为惰性求值,其中 R 在不使用表达式时不会对其求值。正如@SDS0 正确指出的那样,您得到的值是 i=75。我们尝试使用您的原始功能:

    func = function(i){function(e_b,mu_b){i*log(e_b*mu_b) }}
    M_b = 1:3
    log_likelihood = vector("list",3)
    for (idx in 1:3){
           log_likelihood[[idx]] = func(M_b[idx])
         }
    sapply(log_likelihood,function(f)f(5,6))
    
    [1] 10.20359 10.20359 10.20359
    #you get 10.20359 which is M_b[3]*log(5*6)
    

    我刚刚了解到最后一个选项,即 lapply 不再进行惰性求值:

    func = function(i){function(e_b,mu_b){i*log(e_b*mu_b) }}
    log_likelihood = lapply(1:3,function(idx)func(M_b[idx]))
    sapply(log_likelihood,function(f)f(5,6))
    
    [1]  3.401197  6.802395 10.203592
    

    【讨论】:

    • 是的 - 展开,问题是惰性求值 - 函数中的代码在调用函数之前不会被实际求值,此时 i=75。
    • 是的,你是正确的。我正在考虑如何解释惰性评估...
    • 非常感谢您的广泛回答!如果我理解正确并且(正如@SDS0 指出的那样)在调用该函数之前不会评估该函数,我还有另一个问题:我不会准确评估该函数,我想使用优化估计参数 e_b 和 mu_b 。这很重要还是在优化步骤中“评估”了函数?
    • 如果你定义了函数,像以前一样将它存储在一个列表中,然后在优化中使用它,应该没问题。
    猜你喜欢
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多