移交功能电流回路编号

时间:2017-10-25 16:01:42

标签: r

由于这是一个简短的问题,我会遗漏常规背景信息(如果您需要,我会添加它)。 最后有一个名为Coefficients的数据框

Serial_number    Fixed_effects_beta_0    Fixed_effects_beta_1    Fixed_effects_beta_2    Fixed_effects_beta_3    Random_effects_beta_0    Random_effects_beta_1    Random_effects_beta_2    Random_effects_beta_3    p0_fixed    p1_fixed    p2_fixed    p3_fixed    p0_random    p1_random    p2_random    p3_random    Fitted_Voltage
1    912009913    1.238401    13.19572    -0.08379988    1.366747    -0.039642999    -0.40767221    -0.25476169    -0.11315457    -11.92334    0.1177605    -0.0003777831    4.328852e-07    0.56414753    -0.006946270    2.736287e-05    -3.583906e-08    352.9476
(...)

并且对于每行我想要应用函数

inverse = function (f, lower = lower_limit, upper = 450) {
  function (y) uniroot((function (x) f(x) - y), lower = lower_limit, upper = upper)[1]
#  function (y) polyroot((function (x) f(x) - y), lower = lower_limit, upper = upper)[1]
}

function_to_observe = inverse((function(x=150)
  exp(
    exp(
    sum(
        Coefficients[running_row,"p0_fixed"] * x^0,
        Coefficients[running_row,"p1_fixed"] * x^1,
        Coefficients[running_row,"p2_fixed"] * x^2,
        Coefficients[running_row,"p3_fixed"] * x^3
     ))
    )
  )
  , 50, 450)

通过使用存储在数据帧的每一行和某些列中的值,如下所示:

for(i in 1:nrow(Coefficients)){
    Coefficients[i,"Fitted_Voltage"]<- function_to_observe(150)
}

不幸的是,这不起作用,因为Coefficients[i,"Fitted_Voltage"]<- function_to_observe(150)没有处理不同的系数行。 什么是补救措施?为什么我不能做到以下几点:

for(i in 1:nrow(Coefficients)){
    Coefficients[i,"Fitted_Voltage"]<- inverse((function(x=150)
  exp(
    exp(
    sum(
        Coefficients[i,"p0_fixed"] * x^0,
        Coefficients[i,"p1_fixed"] * x^1,
        Coefficients[i,"p2_fixed"] * x^2,
        Coefficients[i,"p3_fixed"] * x^3
     ))
    )
  )
  , 50, 450)
}

这会产生:

Error in x[[jj]][iseq] <- vjj : 
  incompatible types (from closure to double) in subassignment type fix

非常感谢您提供任何帮助!

# Update:
With the help of mathdotrandom I tried a bit and get the following:
lower_limit<- 0
function_to_observe<- inverse((function(x=150)
  exp(
    exp(
      sum(
        Coefficients[i,"p0_fixed"] * x^0,
        Coefficients[i,"p1_fixed"] * x^1,
        Coefficients[i,"p2_fixed"] * x^2,
        Coefficients[i,"p3_fixed"] * x^3
      ))))
  , 50, 550
)


inverse = function (f, lower = lower_limit, upper = 450) {
  function (y) uniroot((function (x) f(x) - y), lower = lower_limit, upper = upper)[1]
}

for(i in 1:nrow(Coefficients)){
  Coefficients[i, "Fitted_Voltage"]<- function_to_observe(150)
}
Coefficients["Fitted_Voltage"]

产生合理的值:

   Fitted_Voltage
1        352.9476
2        352.9476
3        352.9476
4        352.9476
5        352.9476
6        352.9476
7        352.9476
8        352.9476
9        352.9476
10       352.9476
11       352.9476
12       352.9476
13       352.9476
14       352.9476
15       352.9476

虽然我不理解语法,但我认为这是正确的,因为它做了应有的事情。

2 个答案:

答案 0 :(得分:1)

function(x = 150)不运行该函数,但将x设置为默认参数150.因此,您尝试将函数定义放入data.frame中。这就是为什么它抱怨类型闭包(函数)。最简单的方法是给函数命名并在for循环之外定义它,然后调用它。

如果你真的想用它作为lambda函数结帐这个问题和lebatsnok回答:lambda-like functions in R?

反函数不应返回函数而是返回数字。 uniroot函数需要一个函数,所以f应该是你所做的函数。如果你不把它作为参数,R实际上会从上面查找i或running_row的值。

Coefficients <- data.frame("Fitted_Voltage"=c(0,0), "p0_fixed"=c(10^-1, 10^-2),
                           "p1_fixed"=c(10^-2, 10^-3), "p2_fixed"=c(10^-3, 10^-4),
                           "p3_fixed"=c(10^-4, 10^-5))

f <- function(x=150)exp(exp(sum(Coefficients[running_row,"p0_fixed"] * x^0, 
                                Coefficients[running_row,"p1_fixed"] * x^1,                                
                                Coefficients[running_row,"p2_fixed"] * x^2,
                                Coefficients[running_row,"p3_fixed"] * x^3)))

inverse = function (f, lower_limit, upper = 450) {
     y = (f(lower_limit) + f(upper))/2
     uniroot(function(x)(f(x)-y), lower = lower_limit, upper = upper)[1]
}
for(running_row in 1:nrow(Coefficients)){
    Coefficients[i, "Fitted_Voltage"] <- inverse(f,-1,1)
}

但是你的函数总是正数,因为你使用exp和exp(x)&gt; 0 forall x,所以uniroot找不到该函数的零。多根也只能找到多项式的零,但你使用的是exponentail函数。你确定你的函数应该是这样的:e ^(e ^(c_0 + c_1 * x + c_2 * x ^ 2 + c_3 * x ^ 3))? 我减去一个倒数的值,使它有一个根,但我不知道这是否在你的上下文中有任何意义。同样由于双指数,函数变得非常快,所以即使对于小系数,它也会返回Infinity的下限50和上限450,所以我需要做-1和1作为限制来获得一些结果。但这应该与你想要的方式类似。

答案 1 :(得分:1)

遵循mathdotrandom的建议。您可以在外面定义功能。试试这个:

inner.f <- function(x=150, i){
exp(
exp(
  sum(
    Coefficients[i,"p0_fixed"] * x^0,
    Coefficients[i,"p1_fixed"] * x^1,
    Coefficients[i,"p2_fixed"] * x^2,
    Coefficients[i,"p3_fixed"] * x^3
  ))
)
}

然后(如果你想将x设置为150)

Coefficients[i,"Fitted_Voltage"]<- inverse(inner.f(150, i), 50, 450)