This is probably a basic rollapply or loop question, however I can not find a way to instruct the rollapply function or to make an expression for a loop calculation
I have a vector of growth rates with an initial value of 100. I would like to calculate the value at each point of the growth series and obtain a vector of this values. Given that the actual growth series is much longer tan the one below the example below is not possible.
x<-c(0.02,0.01,0.4,0.09,-0.3,0.1)
100*(1+x[1])*(1+x[2])*(1+x[3])*(1+x[4])*(1+x[5])*(1+x[6])#End Value
a1<-100*(1+x[1])#1st value
a2<-a1*(1+x[2])#2nd value
a3<-a2*(1+x[3])#3rd value
a4<-a3*(1+x[4])#4th value
a5<-a4*(1+x[5])#5th value
a6<-a5*(1+x[6])#6th value
s<-c(a1,a,2,a,3,a4,a,5,a6) #vector of values
I believe rollapply could be used here, however I can not write the function as to take the prior value and the next sequentially as to create a function and also I am unsure if and how to incorporate the initial value of 100 in the function or adding it at the beguining of x. In addition maybe this can be done as a loop. (Find the function in pseudo code)
x<-c(0.02,0.01,0.4,0.09,-0.3,0.1)
require(zoo);
fn<- function(y) {(1+prior x)*(1+next x)}
rollapply(x, 1, fun= fn, fill=NA, align='right')
Any help is welcomed
x<-c(0.02,0.01,0.4,0.09,-0.3,0.1)
desired <- 100*(1+x[1])*(1+x[2])*(1+x[3])*(1+x[4])*(1+x[5])*(1+x[6])#End Value
desired
100*tail( cumprod (1+x) , 1)
Oh, dammit. I should have read the comments first. #G.Grothendieck has already been here. I suppose showing how to do it with Reduce could be useful:
> 100*Reduce("*", 1+x)
[1] 121.0506
Related
I have two time series (ts) objects Yt and Yt1 that both contain daily values over five years (start = c(1, 1), end = c(5 ,365), frequency = 365). Yt is an original time series while Yt1 represents a smoothed and gap-filled version of Yt. I want to find the Normalized Root Mean Square Error (NRMSE) between the two time series but I'd like to get one result for each of the five years. For this, I wanted to use the aggregate() function. But since this function only takes one input variable to aggregate, I thought I can just bind the two time series together with ts.union and then call aggregate() on a function that uses matrix subsetting.
So I have data in the form of
Yt <- ts(rnorm(1825), frequency=365) # would be a seasonal signal in reality
Yt1 <- smooth(Yt) # smoothed version of Yt
Yt_union <- ts.union(Yt1, Yt)
and want to apply the NRMSE function
nrmse_fun <- function(Yt_matrix) sqrt(mean((Yt_matrix[,1] - Yt_matrix[,2])^2, na.rm=TRUE)) / mean(Yt_matrix[,2], na.rm=TRUE)
Calling aggregate() like
aggregate(Yt_union, FUN=nrmse_fun)
I expect a result in the form of
Time Series:
Start = 1
End = 5
Frequency = 1
[1] 0.1256365 0.1091591 0.0989738 0.1071725 0.1188176
However, instead I get an error
Error in Yt_matrix[, 1]: incorrect number of dimensions
I know this has probably something to do with the matrix subsetting within the NRMSE function but I don't know how I could rephrase the function so that aggregate() has no problem with it? Using a function with two arguments also wouldn't work since I need both time series to be aggregated simultaneously. I should also mention that I need the result to still be a time series object.
I'm fairly new to R programming so I don't know if there is a simple workaround I'm missing. Maybe aggregate() isn't even needed here? Any help is appreciated!
Looks like I found an easy workaround for this. If I calculate different parts of the NRMSE equation separately I can call aggregate() only when dealing with one time series.
This is my solution:
inner_term <- aggregate((Yt1 - Yt)^2, FUN = mean, na.rm = TRUE)
Yt_mean <- aggregate(Yt, FUN = mean, na.rm = TRUE)
rmse <- sqrt(inner_term)
nrmse <- rmse / Yt_mean
However, since this approach doesn't need simultaneous aggregation over two time series, I'm not sure if another solution exists that is more in line with my initial question. But like #Onyambu suggests, it might just not be possible to use the aggregate() function for matrices.
I'm creating a data frame of a deck of cards (1,2,3,3,4,4,5,6,7,8). Taking a ggplot but applying a tt=sapply(t,card_2), R gives me an error saying dim(X) must have a positive length. Can anyone help me on this? Thank you
This is failing because of the following lines:
sum_a=apply(a,2,sum)
min_a=apply(a,2,min)
sum_b=apply(a,2,sum)
min_b=apply(b,2,min)
The sum and min functions are aggregating functions. They return a single value over a vector (or matrix). You are asking R to iterate over your a and calculate a sum or minimum for each value (which is nonsense). Just do:
sum_a=sum(a)
min_a=min(a)
sum_b=sum(b)
min_b=min(b)
Also, you need to make sure a and b are numeric first.
I am trying to get the half life of a process by finding the time corresponding the half the maximum value of the y-variable and apply it across different cases. I have tried two variations of the which() in R but non of them give me the result I want.
#rc and time are columns of a data.frame
time[which.max(rc)] # gives the time at rc-max, but i need the time at half rc-max
time[which(rc==max(rc)/2] #returns numeric(0)
what can I do to get this value so that I can apply to other cases?
You could do something like this...
time <- 1:10 #sample data
rc <- exp(-(1:10))
uniroot( #finds roots of functions
approxfun(time, rc - max(rc) / 2), #linear interpolation function
range(time) #range of values to check
)$root #value of time where rc=max(rc)/2
[1] 1.790988
See the help pages for these functions for further details and options
I wanted to use rollapply in order to build a rolling window for Value at Risk function. I use the following code:
var<-rollapply(phelix, width=1000, FUN=function(x) VaR(R=phelix, p=0.95, method="historical"),by=1, by.column=TRUE )
phelix is the name of the data vector with returns. It is 3995 observations. I wanted to use a rolling window with 1000 observations. Starting from 1001 and executing the VaR function for every single observation onwards.
After executing the rollapply function I get a vector with 2996 one and the same values. It seems that my window has stuck and doesn't roll :)
Can you please help me with that? Many thanks in advance!
Rollapply repeated calls the function you supply to it with a vector that contains data within the rolling window. In your case you supply FUN=function(x), so x will contain the data within the window. However the function you define has no reference to x so so it always returns the same thing. Assuming that the first argument to VaR is the one that should receive the rolling data, you should use: var<-rollapply(phelix, width=1000, FUN=function(x) VaR(R=x, p=0.95, method="historical"),by=1, by.column=TRUE )
I am still quite new to r (used to program in Matlab) and I am trying use the parallel package to speed up some calculations. Below is an example which I am trying to calculate the rolling standard deviation of a matrix (by column) with the use of zoo package, with and without parallelising the codes. However, the shape of the outputs came out to be different.
# load library
library('zoo')
library('parallel')
library('snow')
# Data
z <- matrix(runif(1000000,0,1),100,1000)
#This is what I want to calculate with timing
system.time(zz <- rollapply(z,10,sd,by.column=T, fill=NA))
# Trying to achieve the same output with parallel computing
cl<-makeSOCKcluster(4)
clusterEvalQ(cl, library(zoo))
system.time(yy <-parCapply(cl,z,function(x) rollapplyr(x,10,sd,fill=NA)))
stopCluster(cl)
My first output zz has the same dimensions as input z, whereas output yy is a vector rather than a matrix. I understand that I can do something like matrix(yy,nrow(z),ncol(z)) however I would like to know if I have done something wrong or if there is a better way of coding to improve this. Thank you.
From the documentation:
parRapply and parCapply always return a vector. If FUN always returns
a scalar result this will be of length the number of rows or columns:
otherwise it will be the concatenation of the returned values.
And:
parRapply and parCapply are parallel row and column apply functions
for a matrix x; they may be slightly more efficient than parApply but
do less post-processing of the result.
So, I'd suggest you use parApply.