Find midpoints between values in vector
Asked Answered
G

4

5

This is for a function to calculate the AUC using the Midpoint Rule. Using R how can I define a vector that contains the midpoints between values of a previous vector? Or how can I shift the values of a vector to their midpoints?

# define h (or delta x)
  h <- (b - a) / n
# define vector based on the limits of integration, a to b by increments of h
  xj <- seq.int(a, b, length.out = n + 1
# shift values of vector to their midpoints

For example, to shift the values [0, 1, 2, 3] to become [.25, 1.5, 2.5]

This for loop works but I am wondering if there is a more elegant solution than this:

for (i in 1:length(xj)) {
  xji[i] <- (xj[i] + xj[i + 1]) / 2
}
Governance answered 31/3, 2018 at 3:31 Comment(1)
did you mean .5 instead of .25?Mama
S
5

We can use a rolling mean

library(zoo)
rollmean(v1, 2)
#[1] 0.5 1.5 2.5

data

v1 <- 0:3
Santalaceous answered 31/3, 2018 at 3:36 Comment(2)
perfect! exactly what I was looking for, something smoother than the for loopGovernance
@Governance Welcome to stack overflow! Thank users who answer your questions by marking their answer as the answer and upvoting when you have that privilege. stackoverflow.com/help/someone-answersHeteroplasty
M
6

For the sake of providing a base R answer, one can use the approx function which will linearly interpolate (by default) a specified number of points.

v <- c(0,1,2,3)
z <- approx(v, n = length(v)*2 - 1)$y
z
# [1] 0.0 0.5 1.0 1.5 2.0 2.5 3.0
z[-which(z %in% v)]
# [1] 0.5 1.5 2.5
Mama answered 2/4, 2018 at 1:57 Comment(0)
S
5

We can use a rolling mean

library(zoo)
rollmean(v1, 2)
#[1] 0.5 1.5 2.5

data

v1 <- 0:3
Santalaceous answered 31/3, 2018 at 3:36 Comment(2)
perfect! exactly what I was looking for, something smoother than the for loopGovernance
@Governance Welcome to stack overflow! Thank users who answer your questions by marking their answer as the answer and upvoting when you have that privilege. stackoverflow.com/help/someone-answersHeteroplasty
C
4

Another solution:

vec <- 0:3
vec[-length(vec)] + diff(vec) / 2
Chaddie answered 11/1, 2019 at 13:29 Comment(1)
Clearly the fastest solution. Even faster would be (vec[-length(vec)] + vec[-1L])/2.Filings
D
1

You can do this easily with RcppRoll package:

require(RcppRoll)

vec <- 0:3
vec2 <- c(1, 3, 5, 7, 8, 10)

roll_mean(vec, n = 2)
# [1] 0.5 1.5 2.5
roll_mean(vec2, n = 2)
# [1] 2.0 4.0 6.0 7.5 9.0
Dilorenzo answered 31/3, 2018 at 3:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.