10

可変時間間隔 (ウィンドウイング) でローリング統計 (ローリング平均、中央値、パーセンタイルなど) を計算する (より高速な) 方法を誰かが思いつくことができるかどうか、私は興味があります。

つまり、ランダムな時間の観測が与えられたとします (つまり、毎日または毎週のデータではなく、観測にはティック データのようにタイム スタンプがあるだけです)。これらの統計が計算される時間間隔を広げたり狭めたりします。

これを行う単純な for ループを作成しました。しかし、明らかに非常に遅く実行されます (実際、速度をテストするために設定したデータの小さなサンプルに対して、ループがまだ実行されていると思います)。私はこれを行うためにddplyのようなものを手に入れようとしています.

例:

サンプルセットアップ:

df <- data.frame(Date = runif(1000,0,30))
df$Price <- I((df$Date)^0.5 * (rnorm(1000,30,4)))
df$Date <- as.Date(df$Date, origin = "1970-01-01")

関数の例(多くの観測で非常に遅く実行されます

SummaryStats <- function(dataframe, interval){
  # Returns daily simple summary stats, 
  # at varying intervals
  # dataframe is the data frame in question, with Date and Price obs
  # interval is the width of time to be treated as a day

  firstDay <- min(dataframe$Date)
  lastDay  <- max(dataframe$Date)
  result <- data.frame(Date = NULL,
                       Average = NULL,  Median = NULL,
                       Count = NULL,
                       Percentile25 = NULL, Percentile75 = NULL)

  for (Day in firstDay:lastDay){

    dataframe.sub = subset(dataframe,
                Date > (Day - (interval/2))
                & Date < (Day + (interval/2)))

    nu = data.frame(Date = Day, 
                    Average = mean(dataframe.sub$Price),
                    Median = median(dataframe.sub$Price),
                    Count = length(dataframe.sub$Price),
                    P25 = quantile(dataframe.sub$Price, 0.25),
                    P75 = quantile(dataframe.sub$Price, 0.75))

    result = rbind(result,nu)

  }

  return(result)

}

あなたのアドバイスは大歓迎です!

4

4 に答える 4

2

上記の「ケビン」への私の質問に答えて、私は以下のことを理解したと思います.

この関数は、ティック データ (タイム オブザベーションがランダムな間隔で取得され、タイム スタンプで示されます) を取得し、間隔の平均を計算します。

library(Rcpp)

cppFunction('
  NumericVector rollmean_c2( NumericVector x, NumericVector y, double width,
                              double Min, double Max) {

double total = 0, redge,center;
unsigned int n = (Max - Min) + 1,
                  i, j=0, k, ledge=0, redgeIndex;
NumericVector out(n);


for (i = 0; i < n; i++){
  center = Min + i + 0.5;
  redge = center - width / 2;
  redgeIndex = 0;
  total = 0;

  while (x[redgeIndex] < redge){
    redgeIndex++;
  }
  j = redgeIndex;

  while (x[j] < redge + width){
    total += y[j++];

  }

  out[i] = total / (j - redgeIndex);
}
return out;

  }')

# Set up example data
x = seq(0,4*pi,length.out=2500)
y = sin(x) + rnorm(length(x),0.5,0.5)
plot(x,y,pch=20,col="black",
     main="Sliding window mean; width=1",
     sub="rollmean_c in red      rollmean_r overlaid in white.")


c.out = rollmean_c2(x,y,width=1,Min = min(x), Max = max(x)) 
lines(0.5:12.5,c.out,col="red",lwd=3)

ここに画像の説明を入力

于 2013-11-23T06:57:15.460 に答える