在 R 中使用 map() rowise
Use map() rowise in R
我有一个 data.frame,我目前正在对其应用 for 循环以获得我想要的结果。但是,我对使用 for 循环并不满意,并且似乎 运行 每隔一段时间就会出现奇怪的错误。我遍历每一行并根据每行中的值计算选项的希腊字母。还有一个“if else”语句决定我是使用看跌期权公式还是看涨期权公式
这是我目前用来获得所需输出的方法。我希望有一种更简洁的方法可以使用 map() 或其他一些函数来做到这一点。谢谢
library(tidyverse)
library(derivmkts)
df = structure(list(pc = c("C", "P", "C", "P", "C", "P", "C", "P",
"C", "P"), spot = c(100, 100, 100, 100, 100, 100, 100, 100, 100,
100), Strike = c(98, 98, 98, 98, 98, 98, 98, 98, 98, 98), iv = c(0.3,
0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3), dte = c(10, 10,
10, 10, 10, 10, 10, 10, 10, 10)), class = "data.frame", row.names = c(NA,
-10L))
head(df)
pc spot Strike iv dte
1 C 100 98 0.3 10
2 P 100 98 0.3 10
3 C 100 98 0.3 10
4 P 100 98 0.3 10
5 C 100 98 0.3 10
#if the pc value is "P" use bsput() otherwise use bscall()
#create list
l = list()
for(i in 1:nrow(df)){
if(df$pc[i] == "P"){
l[[i]] = greeks(bsput(df$spot[i], df$Strike[i], df$iv[i], 0, df$dte[1]/252, 0), complete = T)
} else {
l[[i]] = greeks(bscall(df$spot[i], df$Strike[i], df$iv[i], 0, df$dte[1]/252, 0), complete = T)
}
}
l = do.call(rbind, l)
head(l)
s k v r tt d funcname Premium Delta Vega Rho Theta Psi Elast Gamma
1 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675
2 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672
3 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675
4 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672
5 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675
6 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672
在这种情况下,我很难摆脱 for 循环,希望得到一些帮助。谢谢你
在 R 中,当您需要对 data.frame 中的每一行重复计算时 - 而计算 不 取决于 preceding/succeeding 行,你应该用矢量化来做。查看greeks
,它告诉我们它支持向量化。
但是,对于您的 if-else 设置,您需要做一些子集化。最大的问题是保留顺序:
df$i <- 1:nrow(df)
dte1 <- df$dte[1]/252
df <- df[order(df$pc),]
rows <- df$pc == 'C'
greeks.C <- greeks(bsput(df$spot[rows], df$Strike[rows], df$iv[rows], 0, dte1, 0), complete=T)
greeks.C$i <- df$i[rows]
rows <- df$pc == 'P'
greeks.P <- greeks(bscall(df$spot[rows], df$Strike[rows], df$iv[rows], 0, dte1, 0), complete=T)
greeks.P$i <- df$i[rows]
result <- rbind(greeks.C, greeks.P)
result[order(result$i),]
s k v r tt d funcname Premium Delta Vega Rho Theta Psi Elast Gamma i
1 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 1
6 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 2
2 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 3
7 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 4
3 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 5
8 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 6
4 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 7
9 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 8
5 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 9
10 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 10
我有一个 data.frame,我目前正在对其应用 for 循环以获得我想要的结果。但是,我对使用 for 循环并不满意,并且似乎 运行 每隔一段时间就会出现奇怪的错误。我遍历每一行并根据每行中的值计算选项的希腊字母。还有一个“if else”语句决定我是使用看跌期权公式还是看涨期权公式
这是我目前用来获得所需输出的方法。我希望有一种更简洁的方法可以使用 map() 或其他一些函数来做到这一点。谢谢
library(tidyverse)
library(derivmkts)
df = structure(list(pc = c("C", "P", "C", "P", "C", "P", "C", "P",
"C", "P"), spot = c(100, 100, 100, 100, 100, 100, 100, 100, 100,
100), Strike = c(98, 98, 98, 98, 98, 98, 98, 98, 98, 98), iv = c(0.3,
0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3), dte = c(10, 10,
10, 10, 10, 10, 10, 10, 10, 10)), class = "data.frame", row.names = c(NA,
-10L))
head(df)
pc spot Strike iv dte
1 C 100 98 0.3 10
2 P 100 98 0.3 10
3 C 100 98 0.3 10
4 P 100 98 0.3 10
5 C 100 98 0.3 10
#if the pc value is "P" use bsput() otherwise use bscall()
#create list
l = list()
for(i in 1:nrow(df)){
if(df$pc[i] == "P"){
l[[i]] = greeks(bsput(df$spot[i], df$Strike[i], df$iv[i], 0, df$dte[1]/252, 0), complete = T)
} else {
l[[i]] = greeks(bscall(df$spot[i], df$Strike[i], df$iv[i], 0, df$dte[1]/252, 0), complete = T)
}
}
l = do.call(rbind, l)
head(l)
s k v r tt d funcname Premium Delta Vega Rho Theta Psi Elast Gamma
1 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675
2 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672
3 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675
4 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672
5 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675
6 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672
在这种情况下,我很难摆脱 for 循环,希望得到一些帮助。谢谢你
在 R 中,当您需要对 data.frame 中的每一行重复计算时 - 而计算 不 取决于 preceding/succeeding 行,你应该用矢量化来做。查看greeks
,它告诉我们它支持向量化。
但是,对于您的 if-else 设置,您需要做一些子集化。最大的问题是保留顺序:
df$i <- 1:nrow(df)
dte1 <- df$dte[1]/252
df <- df[order(df$pc),]
rows <- df$pc == 'C'
greeks.C <- greeks(bsput(df$spot[rows], df$Strike[rows], df$iv[rows], 0, dte1, 0), complete=T)
greeks.C$i <- df$i[rows]
rows <- df$pc == 'P'
greeks.P <- greeks(bscall(df$spot[rows], df$Strike[rows], df$iv[rows], 0, dte1, 0), complete=T)
greeks.P$i <- df$i[rows]
result <- rbind(greeks.C, greeks.P)
result[order(result$i),]
s k v r tt d funcname Premium Delta Vega Rho Theta Psi Elast Gamma i
1 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 1
6 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 2
2 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 3
7 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 4
3 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 5
8 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 6
4 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 7
9 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 8
5 100 98 0.3 0 0.03968254 0 bsput 1.493478 -0.3564602 0.07426992 -0.01473790 -0.0769152 0.01414525 -23.86780 0.06238672 9
10 100 98 0.3 0 0.03968254 0 bscall 3.493478 0.6435398 0.07426992 0.02415099 -0.0769152 -0.02553729 18.42118 0.06238675 10