Pelle Pelle - 9 days ago 5
R Question

R: Indexing neigboring values without loop

I like to average out values from a data.frame that are smaller than their neighbors. This is the example:

df <- data.frame(V1 = c(1:10), V2 = c(0.5, 1, 2, 6, 7, 6.5, 8, 8.2, 8.1, 8.5))

for (i in 2:(nrow(df)-1)) {
df[i,2] <- ifelse(
df[i,2] < df[i+1,2] & df[i,2] < df[i-1,2],
mean(c(df[i+1,2], df[i-1,2])),
df[i,2]
)
}


Is there a better way to omit the for-loop?
Thanks in advanced!

989 989
Answer

You could do this vectorized:

inds <- which(with(df, V2<c(NA,head(V2,-1)) & V2<c(tail(V2,-1),NA)))
#[1] 6 9

df$V2[inds] <- (df$V2[inds-1]+df$V2[inds+1])/2

   # V1   V2
# 1   1 0.50
# 2   2 1.00
# 3   3 2.00
# 4   4 6.00
# 5   5 7.00
# 6   6 7.50
# 7   7 8.00
# 8   8 8.20
# 9   9 8.35
# 10 10 8.50