I need to take an existing vector and create a new vector that contains the values;
(x1+2x2−x3, x2+2x3−x4, . . . , xn−2+2xn−1 − xn)
I've tried using xVec[n-2] + 2* xVec[n-1] - xVec[n]
but this doesn't work!
You need a rolling calculation , something that the zoo
package provides:
vec <- 1:10
zoo::rollapply(vec, width = 3, FUN = function(z) z[1]+2*z[2]-z[3])
# [1] 2 4 6 8 10 12 14 16
Validation, using first three and last three:
1 + 2*2 - 3
# [1] 2
8 + 2*9 - 10
# [1] 16
Explanation: each time the function (passed to FUN=
) is called, it is given a vector with width=
elements in it. The first call is effectively z=1:3
, the second call z=2:4
, third z=3:5
, etc.
You should know that by default it will return length(vec) - width + 1
elements in its return value. You can control this with fill=
and align=
arguments:
zoo::rollapply(1:10, width = 3, FUN = function(z) z[1]+2*z[2]-z[3], fill = NA)
# [1] NA 2 4 6 8 10 12 14 16 NA
zoo::rollapply(1:10, width = 3, FUN = function(z) z[1]+2*z[2]-z[3], fill = NA, align = "right")
# [1] NA NA 2 4 6 8 10 12 14 16
Without zoo
:
n <- 10
xVec <- seq(n)
idx <- seq(1, n-2)
xVec[idx] + 2* xVec[idx+1] - xVec[idx+2]
[1] 2 4 6 8 10 12 14 16
In a comment , B. Go has suggested to "reshape" the vector and wonders if this can be done in R as well.
In R, two packages provide functions to shift the elements of a vector: data.table
and dplyr
. (The lag()
function from base R deals with times series objects.)
x <- 1:10
library(data.table)
shift(x, 2L) + 2 * shift(x) - x
[1] NA NA 2 4 6 8 10 12 14 16
x <- 1:10
library(dplyr)
lag(x, 2L) + 2 * lag(x) - x
[1] NA NA 2 4 6 8 10 12 14 16
By default, both functions do fill up missing values after shifting with NA
. This explains why the first two elements of the result vector are NA.
To get rid of the leading NA
s, the tail()
function can be used, eg,
tail(shift(x, 2L) + 2 * shift(x) - x, -2L)
[1] 2 4 6 8 10 12 14 16
If you are up for a bit of matrix math:
xVec <- 1:10
linear_combo <- c(1, 2, -1)
m <- matrix(0, length(xVec), length(xVec))
for (index in seq_along(linear_combo)) {
m[row(m) == col(m) - index + 1] <- linear_combo[index]
}
m %*% xVec
Note in this case the last two elements are incomplete and should probably be dropped or replaced by NA.
head(m %*% xVec, -(length(linear_combo) - 1))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.