Какво ще кажете просто да преминете през (приемайки няколко) 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.
person
eyjo
schedule
11.09.2010