(少数を想定して)N個のインスタンスをループするだけではどうでしょうか。
addZeros <- function(x, N = 3) {
xx <- x
z <- x - 1
for (i in 1:N) {
xx <- xx + c(rep(0, i), z[-c((NROW(x) - i + 1):NROW(x))])
}
xx[xx<0] <- 0
xx
}
後続のN個の値を減算するには、すべてのゼロインスタンスを-1に変換するだけです。
> x <- c(1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1)
> x
[1] 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1
[39] 1 1 1 1 1 1 0 0 1 0 1
> addZeros(x)
[1] 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
[39] 1 1 1 1 1 1 0 0 0 0 0
編集:
R-helpメーリングリストのデータの説明を読んだ後、これは明らかに小さなNの場合ではありません。したがって、このためのC関数を検討することをお勧めします。
ファイル「addZeros.c」:
void addZeros(int *x, int *N, int *n)
{
int i, j;
for (i = *n - 1; i > 0; i--)
{
if ((x[i - 1] == 0) && (x[i] == 1))
{
j = 0;
while ((j < *N) && (i + j < *n) && (x[i + j] == 1))
{
x[i + j] = 0;
j++;
}
}
}
}
コマンドプロンプト(WindowsのMS DOS、Win + rを押してcmdと入力)に、「RCMDSHLIBaddZeros.c」と入力します。Rへのパスに到達できない場合(つまり、「不明なコマンドR」)、完全なアドレスを指定する必要があります(私のシステムでは:
"c:\Program Files\R\R-2.10.1\bin\R.exe" CMD SHLIB addZeros.c
WindowsではDLL(Linuxでは.so)が生成されますが、R-toolboxがまだない場合は、ダウンロードしてインストールする必要があります(PerlやMingwなどのツールのコレクションです)。http://www.murdoch-sutherland.com/Rtools/から最新バージョンをダウンロードし
ます。
このためのRラッパー関数は次のようになります。
addZeros2 <- function(x, N) {
if (!is.loaded("addZeros"))
dyn.load(file.path(paste("addZeros", .Platform$dynlib.ext, sep = "")))
.C("addZeros",
x = as.integer(x),
as.integer(N),
as.integer(NROW(x)))$x
}
setwd("C:/Users/eyjo/Documents/Forrit/R/addZeros")
addZeros R関数が最初に呼び出される前に(または、dyn.load
dllファイルへのフルパスを含めるだけで) 、Rの作業ディレクトリは(私のシステム上の)DLLと同じである必要があることに注意してください。これらをプロジェクトの下のサブディレクトリ(つまり「c」)に保持してから、ファイルパスの「addZeros」の前に「c/」を追加することをお勧めします。
説明する:
> x <- rbinom(1000000, 1, 0.9)
>
> system.time(addZeros(x, 10))
user system elapsed
0.45 0.14 0.59
> system.time(addZeros(x, 400))
user system elapsed
15.87 3.70 19.64
>
> system.time(addZeros2(x, 10))
user system elapsed
0.01 0.02 0.03
> system.time(addZeros2(x, 400))
user system elapsed
0.03 0.00 0.03
>
ここで、「addZeros」は内部Rのみを使用した私の最初の提案であり、addZeros2はC関数を使用しています。