1

毎日の xy 位置と、その位置が外れ値かどうかを示す論理ベクトルで構成されるデータ ファイルがあります。ここにいくつかの(不十分に作成された、私が知っている)サンプルデータがあります:

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()です。outlier=1ただし、値を 6 日間の平均値に含めたくありません。また、outlier=T. 代わりに、「重複しないルール」に例外を設けたいと思います。

これは、上記のサンプル データを使用して最もよく説明されていると思います。最初の値は行 1:6 の平均である必要がありますが、2 番目の値は行 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 重複しますが、最終的な値は一意です)

4

1 に答える 1

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

次のように、すべてを 1 つの関数にまとめることができます。

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
> 
于 2013-10-05T23:00:49.937 に答える