2017-12-01 7 views
0

mit Ich habe den Rahmen folgende Daten:eine neue Variable anlegen, während nachfolgende Werte in r

df1 <- data.frame(id = rep(1:3, each = 5), 
        time = rep(1:5), 
        y = c(rep(1, 4), 0, 1, 0, 1, 1, 0, 0, 1, rep(0,3))) 

df1 
## id time y 
## 1 1 1 1 
## 2 1 2 1 
## 3 1 3 1 
## 4 1 4 1 
## 5 1 5 0 
## 6 2 1 1 
## 7 2 2 0 
## 8 2 3 1 
## 9 2 4 1 
## 10 2 5 0 
## 11 3 1 0 
## 12 3 2 1 
## 13 3 3 0 
## 14 3 4 0 
## 15 3 5 0 

Ich mag würde eine neue Indikatorvariable erstellen, die mir sagt, was für jeden der drei IDs, bei Punkt y = 0 für alle nachfolgenden Antworten. Im obigen Beispiel geschieht dies für die IDs 1 und 2 zum 5. Zeitpunkt und für ID 3 zum 3. Zeitpunkt.

Ich stolpere über ID 2, wo y = 1 zum Zeitpunkt 2, aber dann geht zurück zu eins - ich möchte die Indikatorvariable, um nachfolgende Zeitpunkte zu berücksichtigen.

Im Wesentlichen, ich suche für die folgende Ausgabe:

df1 
## id time y new_col 
## 1 1 1 1  0 
## 2 1 2 1  0 
## 3 1 3 1  0 
## 4 1 4 1  0 
## 5 1 5 0  1 
## 6 2 1 1  0 
## 7 2 2 0  0 
## 8 2 3 1  0 
## 9 2 4 1  0 
## 10 2 5 0  1 
## 11 3 1 0  0 
## 12 3 2 1  0 
## 13 3 3 0  1 
## 14 3 4 0  1 
## 15 3 5 0  1 

Der new_col Variable angibt, ob oder nicht y = 0 zu diesem Zeitpunkt und für alle nachfolgenden Zeitpunkt.

+0

'Bibliothek (dplyr) tun; df1%>% group_by (id)%>% summarize (zero = match (0, y)) 'Wenn Sie eine Spalte benötigen, ändern Sie' summarise' in 'mutate'. Es wäre besser, wenn Sie auch die erwartete Ausgabe anzeigen würden. – akrun

+1

Was wäre, wenn y wieder in Zeile 14 wäre? –

+0

Danke @akrun. Dies ist nicht genau das, was ich für, da für Id 2, Ihre Lösung nicht die Folge '1' zu den Zeitpunkten 3 und 4 berücksichtigen. – afleishman

Antwort

2

Ich würde eine kleine Hilfsfunktion dafür verwenden.

foo <- function(x, val) { 
    pos <- max(which(x != val)) +1 
    as.integer(seq_along(x) >= pos) 
} 

df1 %>% 
    group_by(id) %>% 
    mutate(indicator = foo(y, 0)) 

# # A tibble: 15 x 4 
# # Groups: id [3] 
#  id time  y indicator 
# <int> <int> <dbl>  <int> 
# 1  1  1  1   0 
# 2  1  2  1   0 
# 3  1  3  1   0 
# 4  1  4  1   0 
# 5  1  5  0   1 
# 6  2  1  1   0 
# 7  2  2  0   0 
# 8  2  3  1   0 
# 9  2  4  1   0 
# 10  2  5  0   1 
# 11  3  1  0   0 
# 12  3  2  1   0 
# 13  3  3  0   1 
# 14  3  4  0   1 
# 15  3  5  0   1 

Falls Sie NA-Werte in y betrachten, können Sie einstellen foo:

foo <- function(x, val) { 
    pos <- max(which(x != val | is.na(x))) +1 
    as.integer(seq_along(x) >= pos) 
} 

auf diese Weise, wenn es eine NA nach dem letzten y ist = 0, wird der Indikator bleiben Hier 0.

0

ist eine Option mit data.table

library(data.table) 
setDT(df1)[, indicator := cumsum(.I %in% .I[which.max(rleid(y)*!y)]), id] 
df1 
# id time y indicator 
# 1: 1 1 1   0 
# 2: 1 2 1   0 
# 3: 1 3 1   0 
# 4: 1 4 1   0 
# 5: 1 5 0   1 
# 6: 2 1 1   0 
# 7: 2 2 0   0 
# 8: 2 3 1   0 
# 9: 2 4 1   0 
#10: 2 5 0   1 
#11: 3 1 0   0 
#12: 3 2 1   0 
#13: 3 3 0   1 
#14: 3 4 0   1 
#15: 3 5 0   1 

Basierend auf den Kommentaren von @docendodis cimus, wenn die Werte nicht 0 für 'y' am Ende jedes 'id' sind, dann können wir

setDT(df1)[, indicator := { 
     i1 <- rleid(y) * !y 
    if(i1[.N]!= max(i1) & !is.na(i1[.N])) 0L else cumsum(.I %in% .I[which.max(i1)]) }, id] 
+0

@ Docendodiscimus aktualisieren Es ist nicht klar, dass diese Bedingung beim Lesen des OP-Posts liegt. In Ihrem Code erstellt es alle 0, die ich nicht sicher bin, wenn das ist, was OP beabsichtigt – akrun

+0

@docendodiscimus Ich denke, dass Sie den Code änderten. Ich habe deinen alten Code kopiert/eingefügt. Nun, es ist alles 0s – akrun

+0

@docendodiscimus Wie auch immer, Ihr Code würde auch brechen, wenn der letzte Wert ie y [15] ist NA dh alle 1s geben – akrun

Verwandte Themen