Applying a recursive formula in a loop in r - loops

I got the following recursive formula:
https://i.stack.imgur.com/lma8X.png[1]
Since i cannot embed a picture as a new forum member ( I am only allowed to embed links) I provide you the recursive formula here again:f_n=qf_(n-1)+qpf_(n-2)+qp^2f_(n-3)
The initial conditions are the following:
p=1/2, q=1/2
f_1=0, f_2=0, f_3=p^3=0.125
Now i want to use a loop from i in 4:500.
This means i want to compute f_4, f_5, f_6, f_7,..., f_60.
In R i tried stuff like that:
for (i in 4:500) {
f_i<- qf_(i-1)+qpf_(i-2)+qp^2f_(i-3) }
The problem is that i get the error code that "Error in qf_(i - 1) : could not find function "qf_"".
I am somehow trying to creat new variables using the loop index so that the loop creates
"f_i".
Does somebody know how to tackle this problem?
EDIT:
q<- 1/2
p<- 1-q
f3<-p^3
da<- as.data.frame(matrix(ncol = 2,nrow = 500))
da[1:2,1] <- 0
da[3,1] <- f3
da[,2] <- 1:500
colnames(da) <-c("value","fi")
for (i in 4:500) {
da[i,1] <- q*da[i-1,1]+q*p*da[i-2,1]+q*p^2*da[i-3,1]
}
This works perfectly. However, I was wondering myself if I can create many f_i variables by indexing these new variables through a loop instead of doing it as I did above.

Related

Structuring a for loop to output classifier predictions in python

I have an existing .py file that prints a classifier.predict for a SVC model. I would like to loop through each row in the X feature set to return a prediction.
I am currently trying to define the element from which to iterate over so as to allow for definition of the test statistic feature set X.
The test statistic feature set X is written in code as:
X_1 = xspace.iloc[testval-1:testval, 0:5]
testval is the element name used in the for loop in the above line:
for testval in X.T.iterrows():
print(testval)
I am having trouble returning a basic set of index values for X (X is the pandas dataframe)
I have tested the following with no success.
for index in X.T.iterrows():
print(index)
for index in X.T.iteritems():
print(index)
I am looking for the set of index values, with base 1 if possible, like 1,2,3,4,5,6,7,8,9,10...n
seemingly simple stuff...i haven't located an existing question via stackoverflow or google.
ALSO, the individual dataframes I used as the basis for X were refined with the line:
df1.set_index('Date', inplace = True)
Because dates were used as the basis for the concatenation of the individual dataframes the loops as written above are returning date values rather than
location values as I would prefer hence:
X_1 = xspace.iloc[testval-1:testval, 0:5]
where iloc, location is noted
please ask for additional code if you'd like to see more
the loops i've done thus far are returning date values, I would like to return index values of the location of the rows to accommodate the line:
X_1 = xspace.iloc[testval-1:testval, 0:5]
The loop structure below seems to be working for my application.
i = 1
j = list(range(1, len(X),1)
for i in j:

Making an array out of big number of matrices in r

I'm trying to work with arrays, but I can't seem to make one that works for my data. I have 14 matrices I would like to put in an array, but I can't figure out the way to do it without manually writing c(m1,m2,m3...) to put in all of them
this is what i tried:
m_list <- mget(paste0("well_", 0:13)) ###to make a list of all my matrices
a <- array(c(m_list),
dim = c(7338, 15, 14))
but when I try to look at the array I created something is not right with it cause I try to call for one value, like this:
print(a[1,4,2])
but I get entire columns.
I assume the error is in the list of matrices. Please help
An answer to your question is that you should use do.call(c, m_list) instead of c(m_list). (Take a couple of small matrices and try to see what c(m_list) and c(m1, m2) return.)
Also you might want to think some more whether working with an array is better than working with a list and, more importantly, how you could avoid having multiple matrices in the first place and instead to directly read/define them as a list or an array.
You can simply use unlist inside your array function call instead of c.
a = array(unlist(m_list), dim = c(dim(m_list[[1]]), length(m_list)))
Some reproducible data:
m1 = matrix(1:5, 5, 5)
m2 = matrix(5:1, 5, 5)
m_list = list(m1, m2)

Parallelize nested for-loop on 3 dimensional array in R

Using R on a Windows machine, I am currently running a nested loop on a 3D array (720x360x1368) which cycles through d1 and d2 to apply a function over d3 and assemble the output to a new array of similar dimensionality.
In the following reproducible example, I have reduced the dimensions by factor 10, to make execution faster.
library(SPEI)
old.array = array(abs(rnorm(50)), dim=c(72,36,136))
new.array = array(dim=c(72,36,136))
for (i in 1:72) {
for (j in 1:36) {
new.listoflists <- spi(ts(old.array[i,j,], freq=12, start=c(1901,1)), 1, na.rm = T)
new.array[i,j,] = new.listoflists$fitted
}
}
where spi() is a function from the SPEI package returning a list of lists, of which one particular list $fittedof length 1368 is used from each loop increment to cunstruct the new array.
While this loop works flawlessly, it takes quite a long time to compute. I have read that foreachcan be used to parallelize for loops.
However, I do not understand how the nesting and the assembling of the new array can be achieved such that the dimnames of the old and the new array are consistent.
(In the end, what I want to be able to, is to transform both the old and the new array into a "flat" long panel data frame using as.data.frame.table() and merge them along their three dimensions.)
Any help on how I can achieve the desired output using parallel computing will be highly appreciated!
Cheers
CubicTom
It would have been better with a reproducible example, here is what i come up with:
First create the cluster to use
cl <- makeCluster(6, type = "SOCK")
registerDoSNOW(cl)
Then you create the loop and close the cluster:
zz <- foreach(i = 1:720, .combine = c) %:%
foreach(j = 1:360, .combine = c ) %dopar% {
new.listoflists <- FUN(old.array[i,j,])
new.array[i,j,] <- new.listoflists$list
}
stopCluster(cl)
This will create a list zz containing every iteration of new.array[i,j,], then you can bind them together with:
new.obj <- plyr::ldply(zz, data.frame)
Hope this helps you!
I did not use as much of dimensions as your question because I wanted to ensure the behavior was correct.
So here I use mapply which take multiple arguments. The result is a list of the results. Then I wrapped it with matrix() to get the dimensions you hoped for.
Please note that i is repeated using times and j is repeated using each. This is critical as matrix() put entries by row first then wraps to the next column when the number of row is reached.
new.array = array(1:(5*10*4), dim=c(5,10,4))
# FUN: function which returns lists of
FUN <- function(x){
list(lapply(x, rep, times=3))
}
# result of the computation
result <- matrix(
mapply(
function(i,j,...){
FUN(new.array[i,j,])
}
,i = rep(1:nrow(new.array),times=ncol(new.array))
,j = rep(1:ncol(new.array),each=nrow(new.array))
,new.array=new.array
)
,nrow=nrow(new.array)
,ncol=ncol(new.array)
)

R populate multidimensional array

Hi I am stuck with one of these simple but time-consuming errors:
How can I populate an array with loops? I know I am on a C approach here
and R isn't C.
Data <-[SOMETHING HERE]
One <-200
Two <-100
array222 <- array(0,length(SomeLength))
for (i in 1:One)
{
for (j in 1:Two)
{
array222[i][j] = sample(Data,1)
}
I want to populate the array with random samples from another dataset but all
I get is this:
Warning in array222[i][j] = sample(Data, 1) :
number of items to replace is not a multiple of replacement length
First of all, you wouldn't use loops to do this in R. You'd just do
array222 <- matrix(sample(Data, One*Two, replace=T), nrow=One, ncol=Two)
But going back to your code, you fail to properly initialize your array222 variable. The matrix() syntax is probably easier for a 2-D array, but you could also use array(0, dim=c(One,Two)). You need to create it with the proper dimensions.
And additionally, the proper way to index a dimensional array is
array222[i,j] #NOT array222[i][j]

How can I store a list of ggplots to use in multiplot without overwriting previous plots?

I want to plot some heatmaps of covariance/correlation matrices in a multiplot using an object created from another function (the cd parameter below). The covariance matrices are stored in an array of 3 dimensions, so that cd$covmat[,,i] calls the ith covariance matrix.
Originally I had some issues with this with having the same plot replicated. However, I discovered I had an environment issue. I've tried resolving this several ways, with the code below being the most recent, but I can't figure out why it's not reading it properly.
Is there a particular reason for this? I've tried including and excluding the environment parameter (which I hopefully shouldn't need) and I've tried directly using the cd$covmat[,,i] in the
aes() parameter.
drawCovs<-function(cd,ncols){
require(ggplot2)
coords=expand.grid(x=1:cd$q,y=1:cd$q)
climits = c(-1,1)*max(cd$covmat)
cd$levels=c(cd$levels,"Total")
covtext=ifelse(!(cd$use.cor),'Covariance','Correlation')
plots=list()
cmat=list()
for (i in 1:(nlevels+1)){
cmat[[i]]<-cd$covmat[,,i]
.e<-environment
plots[[i]]<-ggplot(environment=.e)+geom_tile(aes(x=coords$x,y=coords$y,
fill=as.numeric(cmat[[i]]),color='white'))+
scale_fill_gradient(covtext,low='darkblue',high='red',limits=climits)+ylab('')
+xlab('')+guides(color='none')+scale_x_discrete(labels=cd$varnames,
limits=1:cd$q, expand=c(0,0))+scale_y_discrete(labels=cd$varnames,
limits=1:cd$q, expand=c(0,0))+theme(axis.text.x = element_text(angle = 90,
hjust = 1))+labs(title=paste0(covtext,"s of data, ",cd$levels[i]))
}
multiplot(plotlist=plots,cols=ncols)
}
If you end up trying to fix things with direct calls to environments, you are probably overcomplicating your code. Here's a simple snippet that may serve as a core for your function:
drawCovs <- function(cd, ncols) {
require(ggplot2)
require(reshape2)
plots=list()
cmat=list()
for (i in 1:(length(cd$covmat))) {
cmat[[i]] <- cd$covmat[[i]]
plots[[i]] <- ggplot(melt(cmat), aes(x=Var1, y=Var2, fill=value)) +
geom_tile(color='white')
}
multiplot(plotlist=plots,cols=ncols)
}
cd <- list()
cd$covmat <- list(matrix(runif(25), 5), matrix(runif(25), 5))
drawCovs(cd, 1)

Resources