2013-03-07 8 views
5

mam te dane, które nazwałem A:Wstawianie wierszy na podstawie wpisu kolumny i określić pozycję wstawionego wiersza w oparciu o którym wstawia

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) 

A moim celem jest wstawić nowe wiersze z EVID = 2 , ID takie same jak w poprzednim ID rzędu i = czas wprowadzania czasu rzędu poprzedniego powiększonych AMT/dawkę, i żeby nowe rzędy się następuje po pierwszym EVID = 1 po 0s, jak poniżej:

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 

Dostaję się do zindeksowania mojego identyfikatora użytkownika

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

W tej sytuacji ten kod działa lepiej niż ave (EVID, EVID, FUN = seq_along), który indeksowałby wszystkie 1 i wszystkie 0 bez względu na to, czy są ciągłe. Chcę wstawić moje nowe wiersze między Index = 1 a Index = 2 wiersze (po prostu ręcznie usuniemy pierwszy nowy wiersz).

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 

Wynikowy A ma nową kolumnę Index; Chcę, aby nowe wiersze znajdowały się między indeksami 1 i 2, tj. Po rzędzie 1, 6, 13 i 19 w tym przykładzie.

Znalazłem solutions w którym możemy zrobić wektor kolumnowy, a następnie wstawić kolumnę jako wiersz do danych przez zdefiniowany numer wiersza. Jak dodawać wiersze na podstawie wpisu w kolumnie i dynamicznie ustalać pozycje?

Dzięki za pomoc!

+1

to nie jest zupełnie jasne, w jaki sposób określić, gdzie specjalnie, aby wstawić nowy wiersz. Czy możesz rozwinąć proszę –

+0

@RicardoSaporta Dodałem wyjaśnienie; dzięki! – shirleywu

+0

bez prob. proszę spojrzeć poniżej –

Odpowiedz

4

o to rozwiązanie z data.table To naprawdę tylko dwie linie kodu (z odrobiną komentarzach)

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

To działa pięknie! Dziękuję bardzo! – shirleywu

+0

nie ma problemu, chętnie pomoże –

Powiązane problemy