Search code examples
rorg-mode

Printing a list cleanly at the end of a function in R


This works, but as you can see from the output there is a little bit of garbage at the end. How to do this to get rid of the garbage at the end, i.e., the [[1]] : NULL :

#+tblname: prob-calc
| Price              | 353.02 |
| Target price       | 398.00 |
| IV                 |  241.0 |
| Days to expiration |      1 |

#+begin_src R :var tbl=prob-calc   :results output :exports none :session
price = tbl[1,2]
target_price = tbl[2,2]
iv = tbl[3,2]
days = tbl[4,2]
prob_calc <- function(price, target_price, iv, days)
{
    one_sd_move = (price * iv/100 * sqrt(days)) / sqrt(365)
    prob_price_above_target = 1-pnorm((log(target_price/price))/((iv/100)*sqrt(days/365)))
    prob_price_below_target = pnorm(log(target_price/price)/((iv/100)*sqrt(days/365)))
    one_sd_above = price + one_sd_move
    one_sd_below = price - one_sd_move
    ## This won't work, only the last line will be printed
    ## sprintf("One standard deviation move: %f", one_sd_move)
    ## sprintf("Probability stock price closing above the target: %f", prob_price_above_target)
    ## sprintf("Probability stock price closing below the target: %f", prob_price_below_target)
    ## sprintf("One std dev above the current price: %f", one_sd_above)
    ## sprintf("One std dev below the current price: %f", one_sd_below)
    ## Instead, do this:
    return(list(cat("One standard deviation move: ", one_sd_move, "\n",
        "Probability stock price closing above the target: ", prob_price_above_target, "\n",
        "Probability stock price closing below the target: ", prob_price_below_target, "\n",
        "One std dev above the current price: ", one_sd_above, "\n",
        "One std dev below the current price: ", one_sd_below)))
}
prob_calc(price, target_price, iv, days)
#+end_src

#+RESULTS:
: One standard deviation move:  44.53177 
:  Probability stock price closing above the target:  0.1708762 
:  Probability stock price closing below the target:  0.8291238 
:  One std dev above the current price:  397.5518 
:  One std dev below the current price:  308.4882[[1]]
: NULL

Solution

  • As far as I can tell the list() and return() statement are not needed here; but to get rid of the [[1]] NULL just wrap the expression in invisible:

    prob_calc <- function(price, target_price, iv, days) {
      one_sd_move = (price * iv/100 * sqrt(days)) / sqrt(365)
      prob_price_above_target = 1-pnorm((log(target_price/price))/((iv/100)*sqrt(days/365)))
      prob_price_below_target = pnorm(log(target_price/price)/((iv/100)*sqrt(days/365)))
      one_sd_above = price + one_sd_move
      one_sd_below = price - one_sd_move
    
      invisible(
        cat("One standard deviation move: ", one_sd_move, "\n",
             "Probability stock price closing above the target: ", 
              prob_price_above_target, "\n",
             "Probability stock price closing below the target: ", 
              prob_price_below_target, "\n",
             "One std dev above the current price: ", 
              one_sd_above, "\n",
             "One std dev below the current price: ", one_sd_below))
    }
    ##
    R> prob_calc(price, target_price, iv, days)
    One standard deviation move:  44.53177 
     Probability stock price closing above the target:  0.1708762 
     Probability stock price closing below the target:  0.8291238 
     One std dev above the current price:  397.5518 
     One std dev below the current price:  308.4882
    

    Also, you can use sprintf if you put everything in the same text string, which can be done more cleanly with paste0 -

    prob_calc2 <- function(price, target_price, iv, days) {
      one_sd_move = (price * iv/100 * sqrt(days)) / sqrt(365)
      prob_price_above_target = 1-pnorm((log(target_price/price))/((iv/100)*sqrt(days/365)))
      prob_price_below_target = pnorm(log(target_price/price)/((iv/100)*sqrt(days/365)))
      one_sd_above = price + one_sd_move
      one_sd_below = price - one_sd_move
    
      txt <- paste0(
        "One standard deviation move: %f\n",
        "Probability stock price closing above the target: %f\n",
        "Probability stock price closing below the target: %f\n",
        "One std dev above the current price: %f\n",
        "One std dev below the current price: %f\n",
        collapse = "")
    
      cat(sprintf(
        txt, one_sd_move, prob_price_above_target, 
        prob_price_below_target,one_sd_above, one_sd_below))
    }
    ##
    R> prob_calc2(price, target_price, iv, days)
    One standard deviation move: 44.531766
    Probability stock price closing above the target: 0.170876
    Probability stock price closing below the target: 0.829124
    One std dev above the current price: 397.551766
    One std dev below the current price: 308.488234
    

    Data:

    price <- 353.02
    target_price <- 398.00
    iv <- 241.00
    days <- 1