2016-03-15 6 views
5

Lets sagen, ich habe eine solche data.frameFinden erste Folge der Länge n in R

df <- data.frame(signal = c(0, 0, 1, 0, 1, 1, 0, 1, 1, 1)) 

Was ist der beste Weg ist, um erste Signal durch die Zahl diejenigen zu finden, die nacheinander n-mal gehen. Zum Beispiel, wenn n = 1 ist, dann wäre mein Signal drittes Element sein, und ich möchte eine Antwort wie diese bekommen:

c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0) 

für n = 2 Antwort wäre:

c(0, 0, 0, 0, 0, 1, 0, 0, 0, 0) 

Und für n = 3 letztes Element ist Signal nach 3 Einsen in einer Reihe:

c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1) 
+2

Kann es Wiederholungen geben? Könnten Sie "c (0,0,1,0,1,0,1,1,0,1,1,0,1,1,1)" haben? – joran

+0

Sicher kann es Wiederholungen geben – nesvarbu

+1

@nesvarbu Wie sollte die Ausgabe für Wiederholungen aussehen? der letzte oder alle von ihnen? – rawr

Antwort

3
fun <- function(signal, n) { 
    r <- rle(signal == 1) 
    replace(numeric(length(signal)), sum(r$l[seq.int(head(which(r$l * r$v == n), 1))]), 1) 
} 
fun(df$signal, 1) 
# [1] 0 0 1 0 0 0 0 0 0 0 
fun(df$signal, 2) 
# [1] 0 0 0 0 0 1 0 0 0 0 
fun(df$signal, 3) 
# [1] 0 0 0 0 0 0 0 0 0 1 
fun(df$signal, 4) 
# [1] 0 0 0 0 0 0 0 0 0 0 
+0

Es liegt ein Fehler vor, wenn es keine genaue n Anzahl von 1s gibt. – nesvarbu

+0

@nesvarbu, siehe das Update. – Julius

5
x <- c(0, 0, 1, 0, 1, 1, 0, 1, 1, 1) 

y <- rle(x) 
y$values <- y$lengths * y$values 
(y <- inverse.rle(y)) 
# [1] 0 0 1 0 2 2 0 3 3 3 

f <- function(n) {z <- rep(0, length(y)); z[which.max(cumsum(y == n))] <- 1; z} 
f(1) 
# [1] 0 0 1 0 0 0 0 0 0 0 

f(2) 
# [1] 0 0 0 0 0 1 0 0 0 0 

f(3) 
# [1] 0 0 0 0 0 0 0 0 0 1 

Die volle Funktion wäre

g <- function(x, n) { 
    y <- rle(x) 
    y$values <- y$lengths * y$values 
    y <- inverse.rle(y) 
    z <- rep_len(0, length(x)) 
    z[which.max(cumsum(y == n))] <- 1 
    z 
} 
g(x, 1) 
g(x, 2) 
g(x, 3) 

bearbeitet Version 2

g <- function(x, n, ties = c('first','random','last')) { 
    ties <- match.arg(ties) 
    FUN <- switch(ties, first = min, last = max, 
       random = function(x) x[sample.int(length(x), 1)]) 
    y <- rle(x) 
    y$values <- y$lengths * y$values 
    y <- inverse.rle(y) 
    z <- rep_len(0, length(x)) 
    if (!length(wh <- which(y == n))) 
    return(z) 
    wh <- wh[seq_along(wh) %% n == 0] 
    z[FUN(wh)] <- 1 
    z 
} 

x <- c(0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1) 

g(x, 1, 'first') 
# [1] 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 

g(x, 1, 'last') 
# [1] 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 

g(x, 1, 'random') 
# [1] 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 

g(x, 4) 
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
5

Die ersten 1 im Walzprodukt signal mit Fenstergröße = n der Anfang des Signals ist, so

f <- function(x, n){ 
    y <- numeric(length(x)) 
    k <- RcppRoll::roll_prod(x, n) 
    y[which(k==1)[1] + n-1] <- 1 
    y 
} 

> f(df$signal, 1) 
[1] 0 0 1 0 0 0 0 0 0 0 
> f(df$signal, 2) 
[1] 0 0 0 0 0 1 0 0 0 0 
> f(df$signal, 3) 
[1] 0 0 0 0 0 0 0 0 0 1 

Gesundheitsprüfung

set.seed(1) 
signal <- sample(0:1, 10, TRUE) 
signal 
# [1] 0 0 1 1 0 1 1 1 1 0 
f(signal, 3) 
# [1] 0 0 0 0 0 0 0 1 0 0 
g(signal, 3) 
# [1] 1 0 0 0 0 0 0 0 0 0 
fun(signal, 3) 
Error in 1:which(r$len * r$val == n)[1] : NA/NaN argument