0

I've got a list of 137 xts objects, each with 4 variables. Each element is a daily series split by months.

Example code:

recession <- sample(1:100, 4169, replace = TRUE)
unemployed <- sample(1:100, 4169, replace = TRUE)
jobs <- sample(1:100, 4169, replace = TRUE)
insurance <- sample(1:100, 4169, replace = TRUE)
# sequence of daily dates from January 1st 2004 to May 31st 2015:
new1 <- seq(from=as.Date("2004-01-01"), to=as.Date("2015-05-31"), by = "day") 
daily_df <- data.frame(date=as.Date(new1), unemployed, jobs, recession, insurance)
library(xts)
daily_series <- xts(daily_df[-1], order.by = as.Date(new1))
# split daily series into monthly elements of daily data:
split_list <- split(daily_series, f = "months", drop = FALSE, k = 1)

What I want to do is calculate a weighted average across all the variables and elements of the list, so I ran the following code:

monthly_av = NULL
for (i in 1:length(split_list)) {
for (j in 1:ncol(split_list[[i]])) {
monthly_av = cbind(monthly_av, xts(weighted.mean(split_list[[i]][,j]), order.by = index(split_list[[i]][1])))
}}

However, the output it gives me is this:

enter image description here

My desired output is to be an xts object with 137 rows and 4 columns corresponding to the 4 variables. I can't figure out why this is occurring - have I misspecified the loop or is it the cbind function that's doing it?

  • Your weighted mean doesn't have any weights does it? – thelatemail Jul 28 '15 at 06:35
  • I think you should also set `monthly_av` as matrix-like object, and then fill it by row/col index if you want to do it this way `monthly_av = matrix(NA,nrow=i,ncol=j)` and then `monthly_av[i,j] = ....` – thelatemail Jul 28 '15 at 06:40
  • @thelatemail No it doesn't, its set to default. – SAMIR SULTANI Jul 28 '15 at 06:45
  • @thelatemail: Would I set the matrix-like object in the loop, or before it? Given that you specified the rows and columns as i and j. – SAMIR SULTANI Jul 28 '15 at 06:51
  • @thelatemail: It doesn't seem to work. It gives me the following error: `Error in monthly_av[i, j] = cbind(monthly_av, xts(weighted.mean(split_list[[i]][, : number of items to replace is not a multiple of replacement length` – SAMIR SULTANI Jul 28 '15 at 07:07
  • It does work - `monthly_av = matrix(NA,nrow=i,ncol=j)` and then replace your line with: `monthly_av[i,j] = xts(weighted.mean(split_list[[i]][,j]), order.by = index(split_list[[i]][1]))` - Though I'm sure there is a better way than looping. – thelatemail Jul 28 '15 at 22:47

1 Answers1

0

I have found the way to generate a table with monthly weighted average data:

data <- do.call(rbind, 
        lapply(1:length(split_list)
               , function(x) apply(split_list[[x]], 2, weighted.mean)))

> dim(data)
[1] 137   4

And this will mantain an xts object:

data_xts <- do.call(cbind, lapply(1:4, function(x) 
  apply.monthly(daily_series[,x],weighted.mean)))

And using a for loop:

monthly_av = NULL
for (i in 1:ncol(daily_series)){
  monthly_av <- cbind(monthly_av, apply.monthly(daily_series_ts[,i],weighted.mean))
}
Andriy T.
  • 2,020
  • 12
  • 23