I would like to decline (i.e. multiply) a value (first.value) against a vector of percentage decline values (decline.vector), where the first value is declined against the starting percentage decline value, then that output value is declined against the second percentage decline value, and so on. I assume there is a more elegant way to do so in R than writing a for loop to reassign the new value and cbind to create the new vector, but I remain a novice.
The decline vectors are not sequences like below, this just an example.
Although, is it possible to sequence where 'by=' is a vector? I did not find anything in the ?seq that suggests it is possible.
Whereby:
first.value <- 100
decline.vector <- c(0.85, 0.9, 0.925, 0.95, 0.975)
Desired output:
[100] 85, 75.5, 70.763, 67.224, 65.544
You can do this with the Reduce function in base R
first.value <- 100
decline.vector <- c(0.85, 0.9, 0.925, 0.95, 0.975)
Reduce(`*`, decline.vector, first.value, accumulate = TRUE)
# [1] 100.00000 85.00000 76.50000 70.76250 67.22437 65.54377
You could also use cumprod
first.value * cumprod(c(1, decline.vector))
# [1] 100.00000 85.00000 76.50000 70.76250 67.22438 65.54377
If you don't want first.value to be the first element of the output, then do
first.value * cumprod(decline.vector)
# [1] 85.00000 76.50000 70.76250 67.22438 65.54377
Related
I have a min and a max value from each football period (i.e 45, 94 for the second half).
I would like to create two (if possible) equal sized intervals, such as (45, 69) and (70, 94) where the result gets rounded to nearest integer if it is a float.
I've tried using cut() to no avail, and also seq() but I neither than can I figure out how to do.
frame = c(45, 94)
p2.timeslots = cut(frame, 2)
p2.ts = seq(from = frame[1], to = frame[2], by = (frame[2]-frame[1])/2)
# Output
> p2.timeslots
[1] (45,69.5] (69.5,94]
Levels: (45,69.5] (69.5,94]
> p2.ts
[1] 45.0 69.5 94.0
Neither did the length.out argument for seq() solve it for me.
Any idea how I can do this easily in R?
The way cut works is that the bins are contiguous, where the left-side of each bin is typically "open" (denoted by () and right-side "closed" (]). If you assume integers and want both ends to be closed-ends, then you need to manually control both the breaks= and the labels=, perhaps
p2.seq <- seq(frame[1], frame[2], length.out = 3)
p2.seq
# [1] 45.0 69.5 94.0
p2.labels <- sprintf("[%i,%i]", c(p2.seq[1], round(p2.seq[2] + 0.9)), c(round(p2.seq[2] - 0.1), p2.seq[3]))
p2.labels
# [1] "[45,69]" "[70,94]"
cut(frame, breaks = p2.seq + c(-0.1, 0, 0.1), labels = p2.labels)
# [1] [45,69] [70,94]
# Levels: [45,69] [70,94]
The use of + c(-0.1, 0., 0.1) can also be effected by using breaks=p2.seq, include.lowest=TRUE, whichever you prefer.
I have a simple vector, for instance :
a <- c(-1.02, 2.25, 9.12, -2.09, 0.02)
I need to rescale it to an average of 100. But I really don't find the solution in order to solve my problem...
I tried with scale() function in order to rescale the values but however we cannot specify the mean.
I want to have in output when i calculate the mean of the vector : > 100
Thanks in advance for your help !
What about:
rescaled <- a/mean(a)*100
rescaled
[1] -61.594203 135.869565 550.724638 -126.207729 1.207729
mean(rescaled)
[1] 100
scale scales to a mean value of 0, keeping the standard error or scaling it to unity. So just add the desired mean to scale(a) to get a vector with the new mean
b1 <- c(scale(a)) + 100
mean(b1)
#[1] 100
b1
#[1] 99.40138 100.13288 101.66969 99.16202 99.63403
b2 <- c(scale(a, scale = FALSE)) + 100
mean(b2)
#[1] 100
b2
#[1] 97.324 100.594 107.464 96.254 98.364
Note that b2 is equal to
a - mean(a) + 100
#[1] 97.324 100.594 107.464 96.254 98.364
We can use
library(scales)
rescale(a, to = c(0, mean(a))) * 100
Perhaps you can use scale like below
scale(a) + 100
I have a matrix measuring 100 rows x 10 columns:
mat1 = matrix(1:1000, nrow = 100, ncol = 10)
I wish to find the nth percentile of each column using colQuantiles, where the nth percentile is equal to a probability value contained in Probs, except when any of the values in Probs > 0.99 - in which case I want the value of 0.99 applied.
Probs = c(0.99, 0.95, 1, 1, 0.96, 0.92, 1, 0.98, 0.99, 1)
I have tried the following:
Res = ifelse(Probs > 0.99, colQuantiles(mat1, Probs = c(0.99)), colQuantiles(mat1, probs = Probs))
But this simply returns the if true part of the above statement for all ten columns of mat1, presumably because there at least one of the values in Probs is > 0.99. How can I adapt the above so it treats each column of mat1 individually according to the probabilities in Probs?
You can use mapply as follows:
Probs[Probs > 0.99] <- 0.99
unname(mapply(function(x, p) quantile(x, p),
split(mat1, rep(1:ncol(mat1), each = nrow(mat1))),
Probs))
output:
[1] 99.01 195.05 299.01 399.01 496.04 592.08 699.01 798.02 899.01 999.01
It splits the matrix into a set of column vectors (see How to convert a matrix to a list of column-vectors in R?) and then find the nth percentile for each column.
We cannot pass different probability for different columns in colQuantiles but we can get all the probabilities for each column using colQuantiles
temp <- matrixStats::colQuantiles(mat1, probs = pmin(Probs, 0.99))
and then extract the diagonal of the matrix to get the required probability in each column.
diag(temp)
#[1] 99.01 195.05 299.01 399.01 496.04 592.08 699.01 798.02 899.01 999.01
I'm trying to see if there is a way to vectorize a calculation I performed. I searched for this answer and couldn't find what I needed.
I have a vector of growth rates. Each one represents one period (one year in my case). I want to apply this vector to some principal amount. Then, after the first growth rate is applied to the principal, use the result from the first iteration and apply the second growth element to the new value.
Here's some code for reproduction (all in base):
# Vector of interest or inflation rates
RateVector <- c(0.02, 0.03, 0.04, 0.05, 0.06, 0.05, 0.04, 0.03, 0.02, 0.01) # forecasted rates
Principal <- data.frame(Principal = 1000000) # actual value of indicator in most recent period as data frame (list)
Here was my attempt to vectorize:
sapply(Principal, "*", 1 + cumsum(RateVector))
The problem with this is that the sapply function does not save the new amount and instead applies the vector of rates to the same initial principal. This is actually what I expected from this code. I don't know how to go about saving the new value after each iteration from element to element.
This is how I solved the problem, using a loop:
AmountVector <- Principal # initialize output vector
# Compound growth growth calculation loop
for(i in 1:length(RateVector)){
Principal = Principal * (1 + RateVector)[i]
AmountVector <- rbind(AmountVector,Principal)
}
# Print result
AmountVector
This is a "cumulative product", so ?cumprod is what you need:
1000000 * cumprod(1 + RateVector)
# [1] 1020000 1050600 1092624 1147255 1216091 1276895 1327971 1367810 1395166
#[10] 1409118
cbind(AmountVector, newresult = 1000000 * c(1, cumprod(1 + RateVector)))
# Principal newresult
#1 1000000 1000000
#2 1020000 1020000
#3 1050600 1050600
#4 1092624 1092624
#5 1147255 1147255
#6 1216091 1216091
#7 1276895 1276895
#8 1327971 1327971
#9 1367810 1367810
#10 1395166 1395166
#11 1409118 1409118
It's my understanding that when calculating quantiles in R, the entire dataset is scanned and the value for each quantile is determined.
If you ask for .8, for example it will give you a value that would occur at that quantile. Even if no such value exists, R will nonetheless give you the value that would have occurred at that quantile. It does this through linear interpolation.
However, what if one wishes to calculate quantiles and then proceed to round up/down to the nearest actual value?
For example, if the quantile at .80 gives a value of 53, when the real dataset only has a 50 and a 54, then how could one get R to list either of these values?
Try this:
#dummy data
x <- c(1,1,1,1,10,20,30,30,40,50,55,70,80)
#get quantile at 0.8
q <- quantile(x, 0.8)
q
# 80%
# 53
#closest match - "round up"
min(x[ x >= q ])
#[1] 55
#closest match - "round down"
max(x[ x <= q ])
#[1] 50
There are many estimation methods implemented in R's quantile function. You can choose which type to use with the type argument as documented in https://stat.ethz.ch/R-manual/R-devel/library/stats/html/quantile.html.
x <- c(1, 1, 1, 1, 10, 20, 30, 30, 40, 50, 55, 70, 80)
quantile(x, c(.8)) # default, type = 7
# 80%
# 53
quantile(x, c(.8), FALSE, TRUE, 7) # equivalent to the previous invocation
# 80%
# 53
quantile(x, c(.8), FALSE, TRUE, 3) # type = 3, nearest sample
# 80%
# 50