Fill an object with the results of every loop iteration in R - r

first time asker here. I have recently strated working with R and I hope I could get some help with an issue. The problem is probably easy to solve but I haven't been able to find an answer by myself and my research hasn't been succesful either.
Basically I need to create a single object based on the input of a loop. I have 7 simulated asset returns, these objects contain the results from a simulation I ran. I want to match the columns from every object and form a combined one (i.e. every column 1 forms an object), which will be used for some calculations.
Finally, the result from each iteration should be stored on a single object that has to be available outside the loop for further analysis.
I have created the following loop, the problem is that only the result from the last iteration is being written in the final object.
# Initial xts object definition
iteration_returns_combined <- iteration_returns_draft_1
for (i in 2:10){
# Compose object by extracting the i element of every simulation serie
matrix_daily_return_iteration <- cbind(xts_simulated_return_asset_1[,i],
xts_simulated_return_asset_2[,i],
xts_simulated_return_asset_3[,i],
xts_simulated_return_asset_4[,i],
xts_simulated_return_asset_5[,i],
xts_simulated_return_asset_6[,i],
xts_simulated_return_asset_7[,i])
# Transform the matrix to an xts object
daily_return_iteration_xts <- as.xts(matrix_daily_return_iteration,
order.by = index(optimization_returns))
# Calculate the daily portfolio returns using the iteration return object
iteration_returns <- Return.portfolio(daily_return_iteration_xts,
extractWeights(portfolio_optimization))
# Create a combined object for each iteration of portfolio return
# This is the object that is needed in the end
iteration_returns_combined <<- cbind(iteration_returns_draft_combined,
iteration_returns_draft)
}
iteration_returns_combined_after_loop_view
Could somebody please help me to fix this issue, I would be extremely grateful for any information anyone can provide.
Thanks,
R-Rookie

By looking at the code, I surmise that the error is in the last line of your for loop.
iteration_returns_draft_combined
was never defined, so it is assumed to be NULL. Essentially, you only bind columns of the results from each iteration to a NULL object. Hence the output of your last loop is also bound by column to a NULL object, which is what you observe. Try the following:
iteration_returns_combined <- cbind(iteration_returns_combined,
iteration_returns)
This should work, hopefully!

Consider sapply and avoid expanding an object within a loop:
iteration_returns_combined <- sapply(2:10, function(i) {
# Compose object by extracting the i element of every simulation serie
matrix_daily_return_iteration <- cbind(xts_simulated_return_asset_1[,i],
xts_simulated_return_asset_2[,i],
xts_simulated_return_asset_3[,i],
xts_simulated_return_asset_4[,i],
xts_simulated_return_asset_5[,i],
xts_simulated_return_asset_6[,i],
xts_simulated_return_asset_7[,i])
# Transform the matrix to an xts object
daily_return_iteration_xts <- as.xts(matrix_daily_return_iteration,
order.by = index(optimization_returns))
# Calculate the daily portfolio returns using the iteration return object
iteration_returns <- Return.portfolio(daily_return_iteration_xts,
extractWeights(portfolio_optimization))
})
And if needed to column bind first vector/matrix, do so afterwards:
# CBIND INITIAL RUN
iteration_returns_combined <- cbind(iteration_returns_draft_1, iteration_returns_combined)

Related

extra list element is created while creating list of xts in a loop in R

I am trying to create a list of xts objects using a loop:
x <- list()#creating list of xts
#n is number of columns, n is 13
for(i in 1:n-1)
{
x[[(paste0("cor_BG_", i))]]<-as.xts(dcccor[1,i+1,])
}
#binding all correlation pairs together
combined.xts <- do.call("merge.xts", x)
The last line merges all xts files like cor_BG_0,cor_BG_1,cor_BG_3.....up to cor_BG_12. The problem is my loop is supposed to generate xts files with the first element cor_BG_1, As n should be 1 as per the loop for first iteration. However, it is generating the xts cor_BG_0 without passing n=0 in the loop. I am not able to understand how this extra xts is generated and how one can get rid from it.
1:n-1 returns (1-1):(n-1) - that's where the 0 is coming from.
What you need is 1:(n-1).

Storing matrix after every iteration

I have following code.
for(i in 1:100)
{
for(j in 1:100)
R[i,j]=gcm(i,j)
}
gcm() is some function which returns a number based on the values of i and j and so, R has all values. But this calculation takes a lot of time. My machine's power was interrupted several times due to which I had to start over. Can somebody please help, how can I save R somewhere after every iteration, so as to be safe? Any help is highly appreciated.
You can use the saveRDS() function to save the result of each calculation in a file.
To understand the difference between save and saveRDS, here is a link I found useful. http://www.fromthebottomoftheheap.net/2012/04/01/saving-and-loading-r-objects/
If you want to save the R-workspace have a look at ?save or ?save.image (use the first to save a subset of your objects, the second one to save your workspace in toto).
Your edited code should look like
for(i in 1:100)
{
for(j in 1:100)
R[i,j]=gcm(i,j)
save.image(file="path/to/your/file.RData")
}
About your code taking a lot of time I would advise trying the ?apply function, which
Returns a vector or array or list of values obtained by applying a function to margins of an array or matrix
You want gmc to be run for-each cell, which means you want to apply it for each combination of row and column coordinates
R = 100; # number of rows
C = 100; # number of columns
M = expand.grid(1:R, 1:C); # Cartesian product of the coordinates
# each row of M contains the indexes of one of R's cells
# head(M); # just to see it
# To use apply we need gmc to take into account one variable only (that' not entirely true, if you want to know how it really works have a look how at ?apply)
# thus I create a function which takes into account one row of M and tells gmc the first cell is the row index, the second cell is the column index
gmcWrapper = function(x) { return(gmc(x[1], x[2])); }
# run apply which will return a vector containing *all* the evaluated expressions
R = apply(M, 1, gmcWrapper);
# re-shape R into a matrix
R = matrix(R, nrow=R, ncol=C);
If the apply-approach is again slow try considering the snowfall package which will allow you to follow the apply-approach using parallel computing. An introduction to snowfall usage can be found in this pdf, look at page 5 and 6 in particular

Error: number of items to replace is not a multiple of replacement length

I am pretty new to R. So this is a data of 183 columns and multiple rows. I am trying to do a batch forecasting however, I got the error message saying:
"Error in Raw.Data_timeseries_forecast[, i] <- forecast(Raw.Data_timeseries_fit)$mean :
number of items to replace is not a multiple of replacement length"
Could anyone help me to take a look at it?
Thanks!
Raw.Data[is.na(Raw.Data)]<-0
library(forecast)
Raw.Data_timeseries<-msts(Raw.Data[,-1],seasonal.periods = c(7,12,365.25),start=1/1/2014)
ns<-ncol(Raw.Data_timeseries)
h<-365
Raw.Data_timeseries_forecast<-matrix(nrow=h,ncol=ns,byrow =FALSE)
for (i in 1:ns)
{
Raw.Data_timeseries_fit<-stlf(Raw.Data_timeseries[,i])
Raw.Data_timeseries_forecast[,i]<-forecast(Raw.Data_timeseries_fit)$mean
}
write.csv(Raw.Data_timeseries_forecast,"rawdata_stlf.csv")
The issue is that (as far as i can tell, an example of what Raw.Data looks like would help clear it up) is that your line of code :
Raw.Data_timeseries_fit<-stlf(Raw.Data_timeseries[,i])
actually returns a ts object, with a length equal to the whole original Time-series (which I assume is longer than 365 days). You then plug that into the forcast() function, which will output another ts object that is of the original length. However you then try to plug that ts object into the matrix column that has only 365 rows, and thats why it is throwing the "number of items to replace is not a multiple of replacement length" error.
looking at the documentation of the forecast function, you see that it can take both a ts and a model. Looking in the same documentation at the stlf function you see that it is actually a function that creates a stl model and then performs a forecast, so you don't actually need to call:
Raw.Data_timeseries_forecast[,i]<-forecast(Raw.Data_timeseries_fit)$mean
or you could call stlm() instead of stlf and then proceed to call forecast afterwords. Either way however, I'm pretty sure the root problem is in the mismatch between the number of rows of the forecast matrix and the number of observations in the original time series object.
Take a look at the h parameter inside the forecast function, it is returning 2 times your time series length, is that what you want? If no define that explicitly.
You could also solve that problem storing the result into a list:
Raw.Data_timeseries_forecast<-list()
for (i in 1:ns)
{ # i=1
Raw.Data_timeseries_fit<-stlf(Raw.Data_timeseries[,i])
Raw.Data_timeseries_forecast[[i]]<-forecast(Raw.Data_timeseries_fit)$mean
}
Raw.Data_timeseries_forecast_f <- t(do.call("rbind",Raw.Data_timeseries_forecast))
#write.csv(Raw.Data_timeseries_forecast,"rawdata_stlf.csv")

R Shiny: For loop only saves 1 iteration in list

everyone.
I am programming a simulation app in Shiny R and I am stuck at the for loops.
Basically, in an reactive I am calling a function that loops through a couple of other functions, like this:
In the server.R:
output.addiction <- reactive ({
SimulateMultiple(input$no.simulations, vectors(), parameters(), input$S.plus, input$q,
input$weeks, input$d, list.output)
})
The function:
SimulateMultiple <- function (no.simulations, vectors, parameters, S.plus, q, weeks, d, list.output) {
for (i in 1:no.simulations) {
thisi <- i
simulation <- SimulateAddictionComponents(vectors, parameters, S.plus, q, weeks, d) # returns list "simulation"
df.output <- BuildOutputDataframe(weeks, simulation, vectors) # returns "df.outout"
output.addiction <-BuildOutputList(df.output, simulation, list.output) # returns "output.addiction"
}
return(output.addiction)
}
And, again, the last function that creates the out put list:
BuildOutputList <- function (df.output, simulation, list.output) {
addiction <- simulation$addiction
output.w.success <- list(df.output, addiction) # includes success data
output.addition <- c(list.output, list(output.w.success)) # adds the new data to the list
return(output.addition)
}
I read about the issue online a lot, I tried to isolate some stuff, to introduce a local({}) etc. But it never works. In the end, I get a list of length 1.
I would be forever grateful, if you could help me - I have been on this for two days now.
The problem solved itself when I edited the code in the function from
output.addition <- c(list.output, list(output.w.success)) # adds the new data to the list
return(output.addition)
to
list.output <- c(list.output, list(output.w.success)) # adds the new data to the list
return(list.output)
so as to not overwrite the object every time in the loop. After all - very easy and stupid problem, but hard to spot.

Unable to Convert Chi-Squared Values into a Numeric Column in R

I've been working on a project for a little bit for a homework assignment and I've been stuck on a logistical problem for a while now.
What I have at the moment is a list that returns 10000 values in the format:
[[10000]]
X-squared
0.1867083
(This is the 10000th value of the list)
What I really would like is to just have the chi-squared value alone so I can do things like create a histogram of the values.
Is there any way I can do this? I'm fine with repeating the test from the start if necessary.
My current code is:
nsims = 10000
for (i in 1:nsims) {cancer.cells <- c(rep("M",24),rep("B",13))
malig[i] <- sum(sample(cancer.cells,21)=="M")}
benign = 21 - malig
rbenign = 13 - benign
rmalig = 24 - malig
for (i in 1:nsims) {test = cbind(c(rbenign[i],benign[i]),c(rmalig[i],malig[i]))
cancerchi[i] = chisq.test(test,correct=FALSE) }
It gives me all I need, I just cannot perform follow-up analysis on it such as creating a histogram.
Thanks for taking the time to read this!
I'll provide an answer at the suggestion of #Dr. Mike.
hist requires a vector as input. The reason that hist(cancerchi) will not work is because cancerchi is a list, not a vector.
There a several ways to convert cancerchi, from a list into a format that hist can work with. Here are 3 ways:
hist(as.data.frame(unlist(cancerchi)))
Note that if you do not reassign cancerchi it will still be a list and cannot be passed directly to hist.
# i.e
class(cancerchi)
hist(cancerchi) # will still give you an error
If you reassign, it can be another type of object:
(class(cancerchi2 <- unlist(cancerchi)))
(class(cancerchi3 <- as.data.frame(unlist(cancerchi))))
# using the ldply function in the plyr package
library(plyr)
(class(cancerchi4 <- ldply(cancerchi)))
these new objects can be passed to hist directly
hist(cancerchi2)
hist(cancerchi3[,1]) # specify column because cancerchi3 is a data frame, not a vector
hist(cancerchi4[,1]) # specify column because cancerchi4 is a data frame, not a vector
A little extra information: other useful commands for looking at your objects include str and attributes.

Resources