using outer function to get a table of values retu

2020-04-15 15:26发布

问题:

I am a newbie in R and trying to understand the vector way of processing rather than looping. I need help with how to create a table of values using outer function and a user defined function.

Following is a simple function which gives price of a trivial bond

bp = function(y, n=1, c=0, fv=100, freq=2){
  per = 1:(n*freq)
  cf = rep(c/freq, n*freq)
  cf[length(cf)] = cf[length(cf)] + fv
  df = 1/(1+y/freq)^per
  cf %*% df
}

I would like to create a table of bond prices for a vector of yields, n and a given value of c. Some thing like

ylds = c(0.05, 0.07, 0.08)
n = c(1, 5, 10, 15, 20,30)
price_table = outer(ylds, n, bp, c=9)

I anticipate a matrix/array of 18 prices (3x6), but I get this error

###### Start of Error Message

Error in rep(c/freq, n * freq) : invalid 'times' argument

In addition: Warning message:

In 1:(n * freq) : numerical expression has 18 elements: only the first used

#### End of Error Message

What am I doing wrong? And how do I get the desired answer?

Please help.

regards

K

回答1:

outer is expecting your function to be vectorized. As it is written it only makes sense to use bp when n is a scalar. You could rewrite your bp function or you could take advantage of the Vectorize function which will do this for you.

bp = function(y, n=1, c=0, fv=100, freq=2){
  per = 1:(n*freq)
  cf = rep(c/freq, n*freq)
  cf[length(cf)] = cf[length(cf)] + fv
  df = 1/(1+y/freq)^per
  cf %*% df
}

# outer needs the function to be vectorized
# So we ask Vectorize to do this for us.
bpvec <- Vectorize(bp)
ylds = c(0.05, 0.07, 0.08)
n = c(1, 5, 10, 15, 20,30)
price_table = outer(ylds, n, bpvec, c=9)


标签: r outer-join