2016-12-01 59 views
1

我喜歡從data.frame中取平均值小於它們的鄰居。這是例子:無循環索引neigboring值

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] 
    ) 
} 

有沒有更好的方法來省略for循環?

回答

0

你可以這樣做矢量:

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 
0

我們可以嘗試

i1 <- c(FALSE, (df$V2[-nrow(df)] - df$V2[-1])>0 & (df$V2[-1] - df$V2[-nrow(df)]) < 0) 

df$V2[i1] <- sapply(which(i1), function(i) mean(df$V2[c(i-1,i+1)])) 
df$V2 
#[1] 0.50 1.00 2.00 6.00 7.00 7.50 8.00 8.20 8.35 8.50 

或者

i2 <- which(i1) 
df$V2[i2] <- (df$V2[i2-1] + df$V2[i2+1])/2 

或者使用na.approx

library(zoo) 
df$V2 <- na.approx(df$V2*NA^(i1)) 
+2

'i1 < - c(FALSE,diff(df $ V2)<0)'這不會選擇小於先前值的所有值嗎?而不僅僅是那些比之​​前和之後的都少的那些? – rosscova