2017-01-26 16 views
0

私はRで独自の最初のプロジェクトを作成しようとしていますが、ロードブロッキングを打ちました。データフレームのすべての行をループするユーザー定義の関数入力

私は、以下のようなデータフレームを持っています。すべての行が財務オプションのデータセットを表しています。

type <- c("C", "C") 
marketV <- c(1.1166, 1.911) 
S <- c(20, 60) 
K <- c(20, 56) 
T <- c(0.333, 0.5) 
df <- data.frame(type, marketV, S, K, T) 

このデータフレームを入力として使用するユーザー定義関数を作成しました。データフレームが1行の長さである場合、大きな効果がありました。しかし、私はどのように私の関数をすべてのデータフレームの行を反復し、すべての結果を生成するか分からない。

私はRを新しくしたので、 "for"ループを実行したり、lapplyで遊んだりする必要があるのか​​、単純な構文の答えであるのかは分かりません。私は関数が入力としてdfを取るだけで、n行分の計算を繰り返し、n個の結果を生成するだけです。事前に助けてくれてありがとう。

参照として以下の1行を持つDFのための私の現在の機能コード:

+0

'lapply(df、IV)'? – Tensibai

+0

正しい方法で引数を定義していません。関数内で入力した内容(データセット全体を入力したいと思われる点)と、関数内でこの入力をどのように使用するかについて考える必要があります。 'R'はあなたの関数内の' S'、 'K'、' T'が入力の変数であることを知りません。私は関数全体を見ていませんでしたが、関数の先頭に 'attach(df)'を挿入し、 'IV(yourdf)'を呼び出すようにしてください。 – LAP

+0

ありがとう@jogo、あなたは正しいです。これは動作しません。 – LAP

答えて

2

これはあなたのプログラムの修正版です:主なものは、データフレームを通じて行ずつ実行することです

df <- data.frame(type=c("C", "C"), marketV=c(1.1166, 1.911), S=c(20, 60), K=c(20, 56), T=c(0.333, 0.5)) 

IV <- function(df) { 
    # check if df has more then 1 row: 
    if (nrow(df)>1) { message("!! nrow(df)>1 !!"); return(NA) } 

    # Initializing of variables 
    r <- 0 
    sigma <- 0.3 
    sigma_down <- 0.001 
    sigma_up <- 1 
    count <- 0 

    type <- df$type; marketV <- df$marketV; S <- df$S; K <- df$K; T <- df$T 

    d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T)) 
    d2 <- (log(S/K) - (sigma^2/2)*T)/(sigma*sqrt(T)) 

    if(type=="C") { 
    V <- exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2)) 
    } else { 
    V <- exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) } 

    difference <- V - marketV 

    # Root finding of sigma by Bisection method 
    while(abs(difference)>0.001 && count<1000) { 
    if(difference < 0) { 
     sigma_down <- sigma 
     sigma <- (sigma_up + sigma)/2 
    } else { 
     sigma_up <- sigma 
     sigma <- (sigma_down + sigma)/2 
    } 

    d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T)) 
    d2 <- d1 - sigma*sqrt(T) 

    if(type=="C") { 
     V <- exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2)) 
    } else { 
     V <- exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) } 

    difference <- V - marketV 
    count <- count + 1 
    } 
    if(count == 1000){ 
    return(NA)   # If sigma to satisfy Black76 price cannot be found 
    } else{ 
    return(sigma) 
    } 
} 

sapply(split(df, seq(nrow(df))), IV) 

。これはあなたの元の関数では

sapply(split(df, seq(nrow(df))), IV) 

することによって行われ、多くのエラーです:最大のように、SにアクセスしKとされます。あなたはデータフレームdfから値を取ることを考えているかもしれません。しかし実際には、あなたはワークスペースから値を取っていました!私は再定義することによって、これを修正:

type <- df$type; marketV <- df$marketV; S <- df$S; K <- df$K; T <- df$T 

あなたが得るので、私は、dfの行数のためのテストを挿入:

:ここ

> IV(df) 
!! nrow(df)>1 !! 
[1] NA 

は、あなたのプログラムのクリーンアップバージョンです。

df <- data.frame(type=c("C", "C"), marketV=c(1.1166, 1.911), S=c(20, 60), K=c(20, 56), T=c(0.333, 0.5)) 

IV2 <- function(type, marketV, S, K, T) { 
    r <- 0; sigma <- 0.3 
    sigma_down <- 0.001; sigma_up <- 1 
    count <- 0 

    if(type=="C") { 
    f.sig <- function(sigma) { 
     d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T)) 
     d2 <- d1 - sigma*sqrt(T) 
     exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2)) - marketV 
    } 
    } else { 
    f.sig <- function(sigma) { 
     d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T)) 
     d2 <- d1 - sigma*sqrt(T) 
     exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) - marketV 
    } 
    } 
    ifelse(f.sig(sigma_down)*f.sig(sigma_up) < 0, uniroot(f.sig, c(sigma_down,sigma_up))$root, NA) # sigma 
} 

sapply(split(df, seq(nrow(df))), do.call, what="IV2") 
関連する問題