2014-11-13 18 views
5

Celem jest sprawdzenie, czy wartość w indeksie i wynosi 1, a następnie dokonać ostatnich sześciu wpisy jako 1.Jak skonstruować tę zmienną binarną w R?

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

## Required output 
y <- c(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) 

## Attempt 
for(j in seq_along(x)){ 
if(x[j] == 1){ 
    for(i in (j-6):j) 
    x[i] = 1 
    }} 

mógłbyś pomóc rozwiązać ten lub lepsze podejście?

Dzięki.

Odpowiedz

3

Użycie 'za' pętli:

ddf = data.frame(x,y=0) 
for(i in 1:nrow(ddf)){ 
    if(ddf[i,'x']==1){ 
     j = i-5 
     if(j<1) j=1 
     ddf[j:i,'y'] = 1 
    } 
} 
ddf 
    x y 
1 0 1 
2 0 1 
3 0 1 
4 1 1 
5 0 0 
6 0 0 
7 0 0 
8 0 0 
9 0 0 
10 0 0 
11 0 0 
12 0 1 
13 0 1 
14 0 1 
15 0 1 
16 0 1 
17 1 1 
18 0 1 
19 1 1 

y = ddf$y 
y 
[1] 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 
+0

Dzięki za odpowiedź. Czy mógłbyś wyjaśnić, dlaczego moja pętla zwróciła wektor y jak wszystkie 1? Dlaczego potrzebuję tutaj ramki danych? – Anusha

+0

Nie poprawiłeś, jeśli j-6 był mniejszy niż 1. Również data.frame jest łatwiejsza w obsłudze. – rnso

+0

+1. Czy byłoby to możliwe, aby zastosować tę funkcję, a następnie zastosować? Ciekawe, w jaki sposób zostanie zdefiniowany sapply lub lapply dla tej pętli for. – Anusha

2
y<-x 
y[unlist(sapply(which(x==1), 
       function(val){ 
        val:(max(val-6,1)) 
       } 
       ) 
     ) 
    ]<-1 

> y 
[1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

Objaśnienie:

raz pierwszy szukać indeksów x = 1, z which(x==1). Następnie dla każdego z indeksów otrzymam indeksy od tego z x = 1 do szóstego przed tym z sapply(...), a następnie odznaczam wynik, aby mieć tylko wektor indeksów, dla których y musi być 1. I wtedy przypisałem 1 do odpowiednie wartości y.

kolejnym piśmie, w 2 etapach:

y<-x 
ind<-unlist(sapply(which(x==1),function(val){val:(max(val-6,1))})) 
y[ind]<-1 

> y 
[1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 
+0

Dzięki za odpowiedź. Czy możesz wyjaśnić, jak zdefiniowałeś funkcję? Szukałem podejścia * do zastosowania. Jak działa ta część przydziału "<- 1"? – Anusha

+0

@Aushaya, zredagowałem moją odpowiedź, aby dodać wyjaśnienie, powiedz mi, czy to teraz jest OK, czy też potrzebujesz mnie, bym to szczegółowo opisał. – Cath

+0

Zrozumiałem tę część. Jestem ciekawy {val: (max (val-6,1))}))] <- 1, bracketing i logika. – Anusha

5

można spróbować następujących opcji (choć nie zapomnij zainicjować x gdy próbuje każdą opcję jak ja unieważniając go)

indx <- mapply(function(x, y) x:y, which(x == 1) - 6 , which(x == 1)) 
x[indx[indx > 0]] <- 1 
x 
## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

Albo jeszcze prościej

indx <- sapply(which(x == 1) - 6, function(x) x:(x + 6)) 
x[indx[indx > 0]] <- 1 
x 
## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

Albo

indx <- apply(cbind(which(x == 1) - 6 , which(x == 1)), 1, function(x) x[1]:x[2]) 
x[indx[indx > 0]] <- 1 
x 
## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

Albo

indx <- seq_len(6) 
indx <- sapply(which(x == 1), function(x) x - indx) 
x[indx[indx > 0]] <- 1 
x 
## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 
+0

+1.Próbowałem użyć funkcji apply na indeksie, ale nie pomyślałem o wyodrębnieniu indeksów za pomocą zastosowania, a następnie przypisaniu wszystkich do 1. Dzięki za tę logikę. – Anusha

5

W pełni wektorowy rozwiązanie wykorzystujące filter:

as.integer(#turn logical value into numbers 
    as.logical(#coerce to logical --> 0 becomes FALSE, everything else TRUE 
    rev(#reverse order 
    filter(#linear filtering 
     c(rep(0, 6), #pad with zeros in the beginning to avoid NAs 
     rev(x)), #revers order of input vector 
      c(rep(1, 7)), sides=1 #y_i = x_i * 1 + x_(i-1) * 1 +...+ x_(i-6) * 1 
)[-(1:6)]))) #remove NA values 

#[1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 
+0

(+1) Dobra wektoryzacja. –

+0

Czy filtr nie jest używany do obliczania średniej ruchomej? Czy możesz wyjaśnić, jak działa funkcja filtra w tym kontekście? Dzięki. – Anusha

+0

'filter' oblicza ruchomą sumę (dla poprzednich wartości lub dla okna po obu stronach). Jeśli ruchoma suma nie wynosi zero, zmieniam ją w 1. – Roland

Powiązane problemy