如何使用 uniroot 解决数据框中的用户定义函数 (UDF)?

Posted

技术标签:

【中文标题】如何使用 uniroot 解决数据框中的用户定义函数 (UDF)?【英文标题】:How to use uniroot to solve a user-defined function (UDF) in a dataframe? 【发布时间】:2019-03-23 10:45:31 【问题描述】:

我有一个数据框,想在每一行上使用 uniroot 来解决基于 Black-Scholes 公式的隐含波动率。使用 uniroot.all 解决每一行的正确方法是什么?它应该产生一个新的结果列向量。

下面的代码有这个错误

“S/K 中的错误:二元运算符的非数字参数”

。我怀疑当 uniroot 尝试解决多行而不是逐行解决时会出现问题。

我尝试修改为 bscall 函数的矢量化版本,但这似乎不是最好的方法。

df <- data.frame( strike = c(80,120,100,100), 
                  type = c("C", "C", "C","C"),
                  optionPrice = c(22,3,7,9),
                  futurePrice = c(100, 100,100,100),
                  time_to_expiry = c(0.1, 0.1,1,1.2))

bscall <-
  function (S,K,r,T,sig) 
    d1 <- (log(S/K)+(r+0.5*sig^2)*T) / (sig*sqrt(T)) 
    d2 <- d1 - sig*sqrt(T)
    price <- S*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
    return(price)
  


apply(df, 1,
      function(z) uniroot.all( function(x) bscall(z[4],z[1],r,z[5],x) - z[3], interval = c(0,1) ))

【问题讨论】:

【参考方案1】:

df 的第一行是80, "C", 22, 100, 0.1。它包含一个字符串。因此,当您执行apply(df, 1, ....) 时,会将行强制转换为字符向量:

df <- data.frame( strike = c(80,120,100,100), 
                  type = c("C", "C", "C","C"),
                  optionPrice = c(22,3,7,9),
                  futurePrice = c(100, 100,100,100),
                  time_to_expiry = c(0.1, 0.1,1,1.2))

apply(df, 1, function(z) z)
#                [,1]  [,2]  [,3]  [,4] 
# strike         " 80" "120" "100" "100"
# type           "C"   "C"   "C"   "C"  
# optionPrice    "22"  " 3"  " 7"  " 9" 
# futurePrice    "100" "100" "100" "100"
# time_to_expiry "0.1" "0.1" "1.0" "1.2"

【讨论】:

【参考方案2】:

首先:您应该包含用于包rootSolvelibrary 语句。 变量rsig 定义在哪里?

不需要uniroot.all,您可以通过检查函数bscall 看到。不需要迭代; price 直接根据输入计算得出。

考虑到第一个答案,如下定义df。

df <- data.frame( strike = c(80,120,100,100), 
                  # type = c("C", "C", "C","C"),
                  optionPrice = c(22,3,7,9),
                  futurePrice = c(100, 100,100,100),
                  time_to_expiry = c(0.1, 0.1,1,1.2))

type 列已被注释掉。

定义你的函数bscall

bscall <-
  function (S,K,r,T,sig) 
  d1 <- (log(S/K)+(r+0.5*sig^2)*T) / (sig*sqrt(T)) 
  d2 <- d1 - sig*sqrt(T)
  price <- S*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
  return(price)

rsig一个值

r <- .05
sig <- 1

将您的函数应用于df 的行(z 的索引因更改为df 而更改)

apply(df, 1,
   function(z) bscall(z[3],z[1],r,z[4],sig) - z[2])

给予

[1]  2.258107  3.168623 32.840162 34.366636

作为答案。

剩下的看你自己了。

【讨论】:

以上是关于如何使用 uniroot 解决数据框中的用户定义函数 (UDF)?的主要内容,如果未能解决你的问题,请参考以下文章

使用 R 中的多参数用户定义函数将列添加到数据框中

如何从 PySpark 中的数据框中获取模式定义?

C# - 如何检查用户的输入是不是存在于组合框中(使用的数据绑定项)

如何以编程方式用户根据 JavaFX 中的字符串值定义列表视图的颜色

如何根据用户表单组合框选择查询单元格中的数据并将数据复制到用户表单文本框中

将预定义的数字分配给数据框中的列行值