R中的错误陷阱和逻辑

时间:2013-07-07 00:57:29

标签: r input

PresentValue <- function(interest.rate, number.periods, frequency) {

    if (interest.rate > 1) {interest.rate = interest.rate/100} else {"input interest.rate as a    whole number"}
    if (frequency < 1 || frequency > 12 ) {"frequency must be between 1 and 12"} else {interest.rate = interest.rate/frequency}

    (1+interest.rate)^number.periods  
}

上面的代码很简单,但我需要捕获用户输入错误。我看了tryCatch,但这对我没有意义。另外,我认为这不是我现在所需要的。

基本上,我需要做以下事情

首先,确保用户输入的利率为整数(即​​5%不是.05) 其次,我需要“询问”用户如何按月支付费率(频率),每年等等。然后将利率除以频率。

奇怪的是,第一个条件只检查其他if语句何时被注释掉。

这个函数将是一个更大的函数集中的一个对象,所以我认为我需要将它们视为最终将与try catch一起使用的警告。最后,如果在利率误差上函数没有终止,只是要求用户正确输入利率,那就太好了。

提前为简单道歉但却找不到我想要的东西。

编辑添加一些conetxt

以下是更大的功能。这显示了凸度的表输出我需要将持续时间,然后是产量和价格表以及使用swerve输出到页面。这是关于结构性融资的教科书。所以它需要适合学生

Bond.Cash.Flow <-function(issue.date, start.date, end.date, coupon, principal, 
frequency,  price){

library(lubridate)
  issue.date <- as.Date(c(issue.date), "%m-%d-%Y")
  start.date <- as.Date(c(start.date), "%m-%d-%Y")
  end.date <- as.Date(c(end.date), "%m-%d-%Y")
  price = price/100


  # 30/360 day count calculation 
    d1 = day(issue.date)
    m1 = month(issue.date)
    y1 = year(issue.date)
    d2 = day(end.date)
    m2 = month(end.date)
    y2 = year(end.date)


 diff = (max(0, 30 - d1) + min(30, d2) + 360*(y2-y1) + 30*(m2-m1-1))/360
 ncashflows = diff * frequency
 cf.period = seq(1:ncashflows)
 pmtdate = seq(start.date, end.date, by = "6 months")

time.period = (cf.period * 6)/12

 couponincome = rep(coupon/frequency * principal, ncashflows)
 principalincome = rep(0,ncashflows)
 principalincome[ncashflows] = principal
cashflow = couponincome + principalincome


  # Yield to maturity
     irr <- function(rate, time.period, cashflow, principal, price){
      pv = cashflow * 1/(1+rate)^time.period
      proceeds = principal * price
      sum(pv) - proceeds
  }

ytm = uniroot(irr, interval = c(lower = -.20, upper = .20), tol =.000000001, 
time.period = time.period, cashflow = cashflow, principal = principal, price = price)$root

 ytm.vec = c(rep(ytm,ncashflows))
 pv.factor = 1/(1+ytm.vec)^time.period
 pv.cashflow = cashflow*pv.factor
 pv.price = pv.cashflow /(principal * (price/100))
 pv.period = pv.price * time.period
 cvx.time = time.period*(time.period + 1)
 cf.cvx = (cashflow/(1+ytm)^(time.period + 2))/(principal * (price/100))
 cf.cvx.period = cf.cvx * cvx.time

cashflow.table <- data.frame(Period = cf.period, Time = time.period, 
Cashflow = cashflow,  PVFactor = pv.factor,PV = pv.cashflow, PV.Price = pv.price, 
pv.period = pv.period, cvx.time = cvx.time, cf.cvx = cf.cvx, 
cf.cvx.period = cf.cvx.period)


cashflow.table
(sum(pv.period) / (price * 100))/( 1+ (ytm/frequency))
.5 * ((sum(cf.cvx.period)/(price * 100)))
print(xtable(cashflow.table, digits = 4))
}  

Bond.Cash.Flow <-function(issue.date, start.date, end.date, coupon, principal, 
frequency,  price){

library(lubridate)
  issue.date <- as.Date(c(issue.date), "%m-%d-%Y")
  start.date <- as.Date(c(start.date), "%m-%d-%Y")
  end.date <- as.Date(c(end.date), "%m-%d-%Y")
  price = price/100

#30/360天数计算     d1 =天(issue.date)     m1 =月(issue.date)     y1 =年(issue.date)     d2 =天(end.date)     m2 =月(end.date)     y2 =年(end.date)

 diff = (max(0, 30 - d1) + min(30, d2) + 360*(y2-y1) + 30*(m2-m1-1))/360
 ncashflows = diff * frequency
 cf.period = seq(1:ncashflows)
 pmtdate = seq(start.date, end.date, by = "6 months")

time.period = (cf.period * 6)/12

 couponincome = rep(coupon/frequency * principal, ncashflows)
 principalincome = rep(0,ncashflows)
 principalincome[ncashflows] = principal
cashflow = couponincome + principalincome

#到期收益率      irr&lt; - function(rate,time.period,cashflow,principal,price){       pv = cashflow * 1 /(1 + rate)^ time.period       收益=本金*价格       sum(pv) - 收益   }

ytm = uniroot(irr, interval = c(lower = -.20, upper = .20), tol =.000000001, 
time.period = time.period, cashflow = cashflow, principal = principal, price = price)$root

 ytm.vec = c(rep(ytm,ncashflows))
 pv.factor = 1/(1+ytm.vec)^time.period
 pv.cashflow = cashflow*pv.factor
 pv.price = pv.cashflow /(principal * (price/100))
 pv.period = pv.price * time.period
 cvx.time = time.period*(time.period + 1)
 cf.cvx = (cashflow/(1+ytm)^(time.period + 2))/(principal * (price/100))
 cf.cvx.period = cf.cvx * cvx.time

cashflow.table <- data.frame(Period = cf.period, Time = time.period, 
Cashflow = cashflow,  PVFactor = pv.factor,PV = pv.cashflow, PV.Price = pv.price, 
pv.period = pv.period, cvx.time = cvx.time, cf.cvx = cf.cvx, 
cf.cvx.period = cf.cvx.period)


cashflow.table
(sum(pv.period) / (price * 100))/( 1+ (ytm/frequency))
.5 * ((sum(cf.cvx.period)/(price * 100)))
print(xtable(cashflow.table, digits = 4))

}

1 个答案:

答案 0 :(得分:3)

目前尚不清楚您想要做什么,因为您没有给出函数调用的精确上下文。所以我的回答将是不完整的。

  1. 请为您的参数指定默认值,尤其是您有多个要验证的参数的默认值。默认参数在R中使用延迟评估,并且实际上是该语言的强大功能。
  2. 使用stop和/或warning抛出错误/警告并在最终调用上下文中捕获它以向用户发送人工消息。
  3. 看一下match.call(初学者很难)来有效调用你的函数。
  4. 这是使用stop的示例:

    PresentValue <- function(interest.rate, number.periods=1, frequency=1) {
    if (missing(interest.rate))
      stop("Need to specify interest.rate as number between 0 and 1 for calculations.")
    if (!is.numeric(interest.rate)  )
      stop("No numeric  interest.rate specified.")
    if (interest.rate <0 | interest.rate > 1)
      stop("No valid  interest.rate specified.")
     ## you do the same thing for other arguments
    
    }
    

    一些测试:

    PresentValue()
    Error in PresentValue() : 
      Need to specify interest.rate as number between 0 and 1 for calculations.
    > PresentValue("a")
    Error in PresentValue("a") : No numeric  interest.rate specified.
    > PresentValue(5)
    Error in PresentValue(5) : No valid  interest.rate specified.
    > PresentValue(0.9)  ## normal use