Let say I have this data.table:
df = data.table(date = c(20180101, 20180102, 20180103, 20180104, 20180105, 20180106, 20180107, 20180108, 20180109, 20180110, 20180111, 20180112, 20180113, 20180114, 20180115, 20180116, 20180117, 20180118), value = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18))
I want to do some calculations (e.g. mean) that is using subset of data. For example: In 20180103, the average will be the sum of (yesterday) 20180102 and (today) 20180103 value ((2+3)/2 = 2.5). This is then rolling until the end of the period.
Result is like this:
date mean
20180102 1.5
20180103 2.5
20180104 3.5
20180105 4.5
....
Obviously I can write a for loop, subset the data for each iteration then calculate the mean, store the data and output the result. It is deemed too slow using for loop, and using foreach I don't know how to save the result...
The for loop is like:
datelist = df[, .(date)]
# initialize the object
data = NA
temp = 0
for (i in 2:nrow(datelist)) {
today = as.numeric(datelist[i])
yesterday = as.numeric(datelist[i-1])
temp = df[date >= yesterday & date <= today]
temp = temp[, .(mean(value))]
temp = cbind(datelist[i], mean = temp$V1)
if (is.na(data)[1]){
data=temp
} else {
data=rbind(data,temp)
}
}
You can see I first subset the data and call it temp then do the calculation (average, use it to do lm, whatever function then stack it into data object)
This is slow and inefficient as I have millions of data point
Is there anyway I can do this in data.table syntax:
result = df[, { data = .SD[date >= yesterday & date <= today]
mean = mean(data$value)
list(mean = mean)}, by=.(date)]
I don't know how to express yesterday and today?? so that yesterday will be, in the for loop case, i-1 and today is i?
What i understand when doing by=.(date) is that data.table will look at each date and calculate whatever function you give in. If I can get the value (i.e. i) of which date the data.table is looking at now, then the value (i-1) will be yesterday...
Thanks