Как насчет просто циклического обхода (при условии нескольких) 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
}
Просто превращает все нулевые экземпляры в -1, чтобы вычесть N последующих значений.
> 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++;
}
}
}
}
В командной строке (MS DOS в Windows, нажмите Win + r и введите cmd), напишите "R CMD SHLIB addZeros.c".Если путь к R недостижим (например, «неизвестная команда R»), вам нужно указать полный адрес (в моей системе:
"c:\Program Files\R\R-2.10.1\bin\R.exe" CMD SHLIB addZeros.c
В Windows это должно привести к созданию DLL (.so в Linux),но если у вас еще нет 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
}
Обратите внимание, что рабочий каталог в R должен быть таким же, как DLL (в моей системе setwd("C:/Users/eyjo/Documents/Forrit/R/addZeros")
) доФункция addZeros R вызывается в первый раз (в качестве альтернативы, в dyn.load
просто укажите полный путь к файлу dll). Рекомендуется хранить их в подкаталоге проекта (т. е. «c»), затемпросто добавьте «c /» перед «addZeros» в пути к файлу.
Чтобы проиллюстрировать:
> 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.