I am trying to calculate the log returns of a dataset in R using the usual log differencing method. However, the calculated data is simply a vector of zeroes. I can't see what I'm doing wrong.

Here is the snippet showing what I'm doing

> prices <- data$cl
> head(prices)
[1] 1108.1 1095.4 1095.4 1102.2 1096.3 1096.7
> lrets <- log(lag(prices)) - log(prices)
> head(lrets)
[1] 0 0 0 0 0 0
> summary(lrets)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      0       0       0       0       0       0 

What am I doing wrong?

  • 2
    $\begingroup$ lrets <- diff(log(prices)) $\endgroup$ – Vishal Belsare Feb 6 '12 at 11:55
  • 1
    $\begingroup$ @VishalBelsare you should add that as an answer. $\endgroup$ – Louis Marascio Nov 23 '12 at 15:42
  • $\begingroup$ @Patrick Burns, vonjd, aajajim thanks to all of you for answering. I learned new information. $\endgroup$ – thelearner Sep 21 '16 at 12:39

You are simply doing $log(S_t) - log(S_t) = 0$ for all $t$. Instead, try

> n <- length(prices);
> lrest <- log(prices[-1]/prices[-n])

Should do the trick.

  • 11
    $\begingroup$ Or the more traditional, fewer characters: diff(log(prices)) which also works when 'prices' is a matrix with times in the rows and assets in the columns. The other lesson is that 'lag' doesn't do what we naively expect it to do. $\endgroup$ – Patrick Burns Feb 6 '12 at 10:54
  • $\begingroup$ To be sure that lag works as you expect, it is much safer to store your time series as zoo or xts objects: if you use vectors (or even ts objects), many operations will discard or ignore the timestamps. $\endgroup$ – Vincent Zoonekynd Feb 6 '12 at 11:48
  • $\begingroup$ hadnt noticed the "diff" function yet. A handy one, indeed. $\endgroup$ – AdAbsurdum Feb 6 '12 at 12:39
  • $\begingroup$ @PatrickBurns: +1 for your input. I preferred your more succinct syntax. Would have accepted that as an answer. $\endgroup$ – Homunculus Reticulli Feb 6 '12 at 13:06
  • $\begingroup$ i have been using diff(log(prices)) for a while, but was starting to doubt as it seems almost noone use it. thanks :) $\endgroup$ – tagoma Jul 26 '12 at 17:35

I think the simplest method for calculating log returns is ROC from the TTR package:

> data(ttrc)
> roc <- ROC(ttrc[,"Close"])



An easy way to perform what you need is do it this way:

if your data are daily then :

> prices <- data$cl
> log_returns <- diff(log(prices), lag=1)

would provide you with daily log returns, if you change the $lag=1$ to $lag=5$ then you will get weekly moving log returns.

  • $\begingroup$ While I have some experience in finance, I'm new to R (and this site). Question on this post, @aajajim: your suggestion looks very appealing, but another commenter suggests working in zoo, with which I am familiar. Since zoo allows for an irregular times series, how does your answer change if using zoo? $\endgroup$ – W Barker Apr 15 '14 at 18:28
  • $\begingroup$ Doesn't change at all, it's still the same code. At least for my zoo object the function he posted worked without any flaws. $\endgroup$ – Olorun May 31 '14 at 4:09

just to add another method:


for daily log returns, if you have daily prices.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.