2

I have the code below working. But there must be a better way.

file <- "http://s3.amazonaws.com/assets.datacamp.com/production/course_1127/datasets/tmp_file.csv"
x <- read.csv(file = file)
ts <- xts(x = x,  order.by = as.Date(rownames(x), "%m/%d/%Y"))
cd=coredata(ts)
for (j in 1:length(names(ts)))  cd[,j]<-cd[,j]/cd[1,j]
for (j in 1:length(names(ts))) ts[,j]<-cd[,j]
Ray Tayek
  • 9,841
  • 8
  • 50
  • 90

2 Answers2

2

You can create a matrix from your desired scaling row by repeating the row, and then divide the original data by that scaling matrix:

> ts <- xts(x = x,  order.by = as.Date(rownames(x), "%m/%d/%Y"))
> ts
           a b
2015-01-02 1 3
2015-02-03 2 4
> m <- matrix(rep(coredata(ts)[1,], nrow(ts)), ncol = 2, byrow = TRUE)
> m
     [,1] [,2]
[1,]    1    3
[2,]    1    3
> coredata(ts) <- coredata(ts) / m
> ts
           a       b
2015-01-02 1 1.00000
2015-02-03 2 1.33333
> 

That is concise, but the expense of memory. The answer by @TarJae is as nice but possiblt memory efficient so I already upvoted it.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
1

We can use apply to divide each column by its first value:

file <- "http://s3.amazonaws.com/assets.datacamp.com/production/course_1127/datasets/tmp_file.csv"
x <- read.csv(file = file)

library(xts)
ts <- xts(x = x, order.by = as.Date(rownames(x), "%m/%d/%Y"))

ts <- apply(ts, 2, function(x) x / x[1])

           a        b
2015-01-02 1 1.000000
2015-02-03 2 1.333333
TarJae
  • 72,363
  • 6
  • 19
  • 66