2013-03-07 10 views
5

ho questi dati, che ho chiamato A:Inserisci righe sulla base di voce di colonna e determinare l'ingresso della riga inserita in base a dove si inserisce

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) 

e il mio obiettivo è inserire nuove righe con EVID = 2 , ID lo stesso del ID precedente riga e TEMPO = ingresso tempo che precede di fila più AMT/dose, e voglio le nuove righe da seguire dopo la prima EVID = 1 dopo gli 0, come di seguito:

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 

Mi arriva fino all'indicizzazione dei miei EVID

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

In questo caso, questo codice funziona meglio di ave (EVID, EVID, FUN = seq_along) che indicizzerebbe tutti gli 1 e tutti gli 0 indipendentemente dal fatto che siano continui. Voglio inserire le mie nuove righe tra Index = 1 e Index = 2 righe (eliminerò solo manualmente la prima nuova riga).

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 

La risultante A ha una nuova colonna Indice; Voglio che le nuove righe siano tra l'indice 1 e 2, vale a dire dopo le righe numero 1, 6, 13 e 19 in questo esempio.

Mi sono imbattuto in solutions in cui è possibile creare un vettore di colonna, quindi inserire la colonna come riga nei dati per numero di riga definito. Come aggiungo le righe in base alla voce della colonna e determinate dinamicamente alcune voci?

Grazie per il vostro aiuto!

+1

non è del tutto chiaro come si determina dove specificamente per inserire la nuova riga. Potete elaborare per favore –

+0

@RicardoSaporta Ho aggiunto il chiarimento; Grazie! – shirleywu

+0

no prob. si prega di dare un'occhiata sotto –

risposta

4

Ecco una soluzione con data.table E 'davvero solo due righe di codice (con un po' di commenti)

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

Questo funziona magnificamente! Grazie mille! – shirleywu

+0

nessun problema, felice di aiutare –

Problemi correlati