2013-03-07 6 views
5

fügt ich diese Daten haben, die ich A genannt:Zeilen einfügen basierend auf Spalteneintrag und bestimmen die Eingabe der Zeile eingefügt, basierend auf, wo es

A <- read.table(text = "ID TIME EVID AMT DOSE 
1 10  1  100 20 
1 12  1  100 20 
1 14  1  100 20 
1 16  1  100 20 
1 17  0  100 20 
1 18  1  100 20 
1 20  1  100 20 
1 22  1  100 20 
2 5  1  100 40 
2 10  1  100 40 
2 15  1  100 40 
2 17  0  100 40 
2 20  1  100 40 
3 4  1  100 25 
3 7  1  100 25 
3 10  1  100 25 
3 11  0  100 25 
3 13  1  100 25 
3 16  1  100 25 
3 19  1  100 25", header = TRUE) 

Und mein Ziel ist es, neue Zeilen einfügen mit EVID = 2 ID, das gleiche wie die vorhergehenden Zeilen-ID, und TIME = vorhergehende Zeile der TIME-Eintrag Plus AMT/DOST, und ich die neuen Zeilen will nach dem ersten EVID folgen = 1 nach dem 0er, wie unten:

ID TIME EVID AMT DOSE 
1 10  1  100 20 
1 12  1  100 20 
1 14  1  100 20 
1 16  1  100 20 
1 17  0  100 20 
1 18  1  100 20 
1 23  2  100 20 
1 20  1  100 20 
1 22  1  100 20 
2 5  1  100 40 
2 10  1  100 40 
2 15  1  100 40 
2 17  0  100 40 
2 20  1  100 40 
2 22.5 2  100 40 
3 4  1  100 25 
3 7  1  100 25 
3 10  1  100 25 
3 11  0  100 25 
3 13  1  100 25 
3 17  2  100 25 
3 16  1  100 25 
3 19  1  100 25 

Ich komme so weit zur Indexierung meiner EVIDs

rle(as.character(EVID))$lengths 
A$Index<-unlist(sapply(rle(as.character(EVID))$lengths, seq_len), use.names = FALSE) 

In diesem Fall funktioniert dieser Code besser als ave (EVID, EVID, FUN = seq_along), die alle 1s und alle 0s indexieren würden, unabhängig davon, ob sie kontinuierlich sind. Ich möchte meine neuen Zeilen zwischen Index = 1 und Index = 2 Zeilen einfügen (ich werde nur die erste neue Zeile manuell löschen).

ID TIME EVID AMT DOSE Index 
1 1 10 1 100 20  1 
2 1 12 1 100 20  2 
3 1 14 1 100 20  3 
4 1 16 1 100 20  4 
5 1 17 0 100 20  1 
6 1 18 1 100 20  1 
7 1 20 1 100 20  2 
8 1 22 1 100 20  3 
9 2 5 1 100 40  4 
10 2 10 1 100 40  5 
11 2 15 1 100 40  6 
12 2 17 0 100 40  1 
13 2 20 1 100 40  1 
14 3 4 1 100 25  2 
15 3 7 1 100 25  3 
16 3 10 1 100 25  4 
17 3 11 0 100 25  1 
18 3 13 1 100 25  1 
19 3 16 1 100 25  2 
20 3 19 1 100 25  3 

Das resultierende A hat eine neue Indexspalte; Ich möchte, dass die neuen Zeilen zwischen dem Index 1 und 2 liegen, d. H. Nach den Zeilennummern 1, 6, 13 und 19 in diesem Beispiel.

Ich habe solutions in denen wir einen Spaltenvektor machen können, dann fügen Sie die Spalte als Zeile in die Daten durch definierte Zeilennummer. Wie füge ich die Zeilen basierend auf dem Spalteneintrag hinzu und ermittelte einige Einträge dynamisch?

Danke für Ihre Hilfe!

+1

es nicht ganz klar ist, wie Sie bestimmen, wo speziell die neue Zeile einzufügen. Können Sie bitte –

+0

@RicardoSaporta erarbeiten Ich habe die Klarstellung hinzugefügt; Vielen Dank! – shirleywu

+0

kein Problem Bitte schauen Sie unter –

Antwort

4

hier ist eine Lösung mit data.table wirklich zwei Es ist nur Codezeilen (mit einem bisschen Kommentar)

library(data.table) 
ADT <- data.table(row=1:nrow(A), A, key="ID") 

# just to give an idea of how we can Find the first 0 after the first 1, look at the output from this 
ADT[, list(row, EVID,c(NA,diff(EVID)), c(NA,diff(EVID))==1)] 

# identify afer which row to insert 
# the values you want to change, assign using the `=` 
# the values to keep, just call the variable name, no `=` sign 
newRows <- ADT[c(NA,diff(EVID))==1, list(row=row+1, ID, TIME=TIME+AMT/DOSE, EVID=2, AMT, DOSE)] 

# rbind the new rows with the original DT 
# then reverse order by EVID, and order by row. 
# After ordering, remove the first column (`row`) since it is not needed 
newA <- rbind(ADT, newRows)[order(EVID, decreasing=TRUE)][order(row)][, -1, with=FALSE] 


### Results: 

> newA 
    ID TIME EVID AMT DOSE 
1: 1 10 1 100 20 
2: 1 12 1 100 20 
3: 1 14 1 100 20 
4: 1 16 1 100 20 
5: 1 17 0 100 20 
6: 1 18 1 100 20 
7: 1 23 2 100 20 
8: 1 20 1 100 20 
9: 1 22 1 100 20 
10: 2 5 1 100 40 
11: 2 10 1 100 40 
12: 2 15 1 100 40 
13: 2 17 0 100 40 
14: 2 20 1 100 40 
15: 2 22 2 100 40 
16: 3 4 1 100 25 
17: 3 7 1 100 25 
18: 3 10 1 100 25 
19: 3 11 0 100 25 
20: 3 13 1 100 25 
21: 3 17 2 100 25 
22: 3 16 1 100 25 
23: 3 19 1 100 25 
    ID TIME EVID AMT DOSE 
+0

Das funktioniert wunderbar! Ich danke dir sehr! – shirleywu

+0

kein Problem, froh zu helfen –

Verwandte Themen