Simple R task: divide specified columns by 1000 at specified rows
Question
I have an OHLC array of stock quotes that I want to process.
Open High Low Close Volume
2003-01-05 6111.01 6145.00 6102.70 6145.00 956
2003-01-08 6145.00 6190.00 5960.00 6135.05 8771
2003-01-09 6120.01 6250.00 6120.00 6225.00 10579
2003-01-10 6240.00 6285.00 6225.10 6261.00 8882
2003-01-13 6231.00 6325.00 6231.00 6270.00 8015
2003-01-14 6279.00 6295.00 6180.01 6190.00 8461
The company made a split @ given date, so I need to divide all open,high,low,close columns before that date by 1000. As I am learning R basics now I want to figure out nice R solution for this task. The best piece of code I've managed to code is (cant find out how to apply to given cols, stock$Open doesn't work):
apply(stock, 2, function(stock) stock/((index(stock)<"2007-07-20")*1000) )
However, the results are strange, many of them are inf:
2006-10-26 Inf Inf Inf Inf Inf
2006-10-27 Inf Inf Inf Inf Inf
2006-10-30 Inf Inf Inf Inf Inf
2006-10-31 Inf Inf Inf Inf Inf
2006-11-01 Inf Inf Inf Inf Inf
2006-11-02 Inf Inf Inf Inf Inf
2006-11-03 Inf Inf Inf Inf Inf
2006-11-07 Inf Inf Inf Inf Inf
Many thanks in advance!
Solution
I'm not familiar with OHLC array
s, but assuming that index method works:
relevantRows<-index(stock) < "2007-07-20"
Once you've got a vector holding all the relevant rows (in fact a logical vector that holds TRUE for the rows that should be changed), you can probably use this simply like this:
stock$Open[relevantRows]<-stock$Open[relevantRows]/1000
It is possible (depending on the internals of OHLC array
s), that even this works:
stock[relevantRows, c("Open", "High", "Low", "Close")]<-stock[relevantRows, c("Open", "High", "Low", "Close")]/1000
OTHER TIPS
If the date is not before 20/7/2007, then (index(stock)<"2007-07-20")
is FALSE
and so (index(stock)<"2007-07-20")*1000
comes out as zero. Your Inf
values are a result of dividing by zero.
You could try this:
stock[index(stock) < "2007-07-20", -5] <- stock[index(stock) < "2007-07-20", -5] / 1000
You can use the adjRatios
function in the TTR package to do this. It looks like you already have an xts object, so that's what I use:
library(quantmod)
x <- structure(c(6111.01, 6145, 6120.01, 6240, 6231, 6279, 6145, 6190,
6250, 6285, 6325, 6295, 6102.7, 5960, 6120, 6225.1, 6231, 6180.01,
6145, 6135.05, 6225, 6261, 6270, 6190, 956, 8771, 10579, 8882,
8015, 8461), .Dim = c(6L, 5L), .Dimnames = list(NULL, c("Open",
"High", "Low", "Close", "Volume")), index = structure(c(1041746400,
1042005600, 1042092000, 1042178400, 1042437600, 1042524000), tzone = "",
tclass = "Date"), class = c("xts", "zoo"), .indexCLASS = "Date", .indexTZ = "")
s <- xts(1/1000,as.Date("2003-01-10"))
r <- adjRatios(s,,Cl(x))
OHLC(x) * drop(r[,"Split"]) * drop(r[,"Div"])
If you're using data from Yahoo Finance, then you can use the adjustOHLC
function in quantmod to automatically pull split and dividend data from Yahoo and adjust the series. See ?adjustOHLC
for more options.