2013-10-05 91 views
1

我具有由每日XY位置和表示位置是否是異常值的邏輯矢量的數據文件。下面是一些(創建不好,我知道)樣本數據:rollapply改性意味着

x=seq(3,10,length.out=30) 
y=seq(42,45,length.out=30) 
outlier=c(F,F,F,F,F,F,F,F,T,T,T,F,F,F,F,F,F,F,F,F,F,T,F,T,F,F,F,F,F,F) 
data=cbind(x,y,outlier) 
> data 
      x   y outlier 
[1,] 3.000000000 42.00000000  0 
[2,] 3.241379310 42.10344828  0 
[3,] 3.482758621 42.20689655  0 
[4,] 3.724137931 42.31034483  0 
[5,] 3.965517241 42.41379310  0 
[6,] 4.206896552 42.51724138  0 
[7,] 4.448275862 42.62068966  0 
[8,] 4.689655172 42.72413793  0 
[9,] 4.931034483 42.82758621  1 
[10,] 5.172413793 42.93103448  1 
[11,] 5.413793103 43.03448276  1 
[12,] 5.655172414 43.13793103  0 
[13,] 5.896551724 43.24137931  0 
[14,] 6.137931034 43.34482759  0 
[15,] 6.379310345 43.44827586  0 
[16,] 6.620689655 43.55172414  0 
[17,] 6.862068966 43.65517241  0 
[18,] 7.103448276 43.75862069  0 
[19,] 7.344827586 43.86206897  0 
[20,] 7.586206897 43.96551724  0 
[21,] 7.827586207 44.06896552  0 
[22,] 8.068965517 44.17241379  1 
[23,] 8.310344828 44.27586207  0 
[24,] 8.551724138 44.37931034  1 
[25,] 8.793103448 44.48275862  0 
[26,] 9.034482759 44.58620690  0 
[27,] 9.275862069 44.68965517  0 
[28,] 9.517241379 44.79310345  0 
[29,] 9.758620690 44.89655172  0 
[30,] 10.000000000 45.00000000  0 

我需要的是把x和y列的非重疊6日均值。這很容易與rollapply()。不過,我不希望被包含在6天的平均outlier=1值;我也不想要了6天的窗口,以「跨越」通過刪除所有行outlier=T留下的缺口。相反,我想對「不重疊的規則」進行例外。

我認爲這是使用上面的示例數據最好的解釋:第一個值應該是行1:6的平均值,而不是第7:12行的平均值(包括outlier=1值)或列C(7:8,12:15)(跳過outlier=1值)我希望它與所述第一窗口交疊,並採取行3的平均:8。

因此,對於上面30個樣本數據的長度,最終結果應該是長度5,顯示行1:6,3:8,12:17,16:21的平均值。& 25:30(理想情況下全部從重疊窗口,其結果值被標記爲這樣,即值1:4的重疊,而最終值是唯一的)

+0

我不明白怎麼這rollaply這確實移動平均相關(這樣你就不會得到非overalapping結果)。簡單的版本可以用聚合來完成,而不是滾動式的。至於你的複雜版本,你需要先把它寫成一組if-then規則。例如,如果前兩種情況是「異常值」會發生什麼?如果有異常,你總是移動的「窗口」向上,直到你有非離羣的期望是多少?如果連續有6個異常值,那麼你會有兩個相同的項目嗎? – lebatsnok

回答

2

這裏是會給你所需的平均的端點的索引的函數:

findIndices<-function(outlier,window=6){ 
    r<-rle(outlier) 
    rends<-cumsum(r$lengths) 
    segs<-cbind(rends-r$lengths+1,rends) 
    segs<-segs[with(r,lengths>=window & values==0),] 

    indices<-unlist(apply(segs,1,function(x) seq(x[1]+window-1,x[2],by=window))) 
    sort(unique(c(indices,segs[,2])))  
} 

findIndices(data[,3]) 
## [1] 6 8 17 21 30 

那麼你可以得到你想要這樣的場均數據:

id<-findIndices(data[,3]) 
require(zoo) 
cbind(index=id,rollmean(data[,1:2],6)[id-5,]) 
##  index  x  y 
## [1,]  6 3.603448 42.25862 
## [2,]  8 4.086207 42.46552 
## [3,] 17 6.258621 43.39655 
## [4,] 21 7.224138 43.81034 
## [5,] 30 9.396552 44.74138 

你可以把它一起在一個單一的功能是這樣的:

maWithOutliers<-function(x,outlier,window){ 
    id<-findIndices(outlier,window) 
    cbind(index=id,rollmean(x,window)[id-window+1,]) 
} 

> maWithOutliers(data[,1:2],data[,3],6) 
    index  x  y 
[1,]  6 3.603448 42.25862 
[2,]  8 4.086207 42.46552 
[3,] 17 6.258621 43.39655 
[4,] 21 7.224138 43.81034 
[5,] 30 9.396552 44.74138 
> maWithOutliers(data[,1:2],data[,3],4) 
    index  x  y 
[1,]  4 3.362069 42.15517 
[2,]  8 4.327586 42.56897 
[3,] 15 6.017241 43.29310 
[4,] 19 6.982759 43.70690 
[5,] 21 7.465517 43.91379 
[6,] 28 9.155172 44.63793 
[7,] 30 9.637931 44.84483 
>