# Calculating log returns using R

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)  1108.1 1095.4 1095.4 1102.2 1096.3 1096.7 > > > lrets <- log(lag(prices)) - log(prices) > head(lrets)  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? • lrets <- diff(log(prices)) – Vishal Belsare Feb 6 '12 at 11:55 • @VishalBelsare you should add that as an answer. – Louis Marascio Nov 23 '12 at 15:42 • @Patrick Burns, vonjd, aajajim thanks to all of you for answering. I learned new information. – thelearner Sep 21 '16 at 12:39 ## 5 Answers 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. • 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. – Patrick Burns Feb 6 '12 at 10:54 • 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. – Vincent Zoonekynd Feb 6 '12 at 11:48 • hadnt noticed the "diff" function yet. A handy one, indeed. – AdAbsurdum Feb 6 '12 at 12:39 • @PatrickBurns: +1 for your input. I preferred your more succinct syntax. Would have accepted that as an answer. – Homunculus Reticulli Feb 6 '12 at 13:06 • i have been using diff(log(prices)) for a while, but was starting to doubt as it seems almost noone use it. thanks :) – tagoma Jul 26 '12 at 17:35 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.

• 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? – W Barker Apr 15 '14 at 18:28
• 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. – Olorun May 31 '14 at 4:09

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

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


https://CRAN.R-project.org/package=TTR

>lrtn=diff(log(prices))


for daily log returns, if you have daily prices.

if you want to get rid of the first NA produced you can either start at 0 or omit the first row like this:

require(quantmod)
getSymbols("MSFT")
MSFT$$Log_Returns <- diff(log(MSFT$$Adjusted)); MSFT\$Log_Returns <- 0 # this will make the first row of your returns series equal 0, which arguably is correct for any starting date.

MSFT$$Log_Returns <- diff(log(MSFT$$Adjusted))
MSFT <- MSFT[2:nrow(MSFT),] # this option will remove the first row which is a NA and therefore not introduce a 0.


Both options work fine, hope it helps.