2011-08-18 18 views
5

Sono un socio no.Max con movimento condizionato

Ho un grande insieme di dati che sembra qualcosa di simile:

  Tempadjvolt  newmass  rgdeltas 
2794  498.5777 0.5355647187 0.00000000 
2795  499.7577 0.5355647187 0.00000000 
2796  500.7877 0.3415104788 -2.87487763 
2797  502.1177 0.4312854788 -1.54487763 
2798  500.3877 0.5355647187 0.00000000 
2799  502.5377 0.4596354788 -1.12487763 
2800  507.6877 0.8072604788 4.02512237 
2801  505.2577 0.6432354788 1.59512237 
2802  505.7977 0.6796854788 2.13512237 
2803  517.8877 1.4957604788 14.22512237 
2804  502.2477 0.4400604788 -1.41487763 
2805  507.3677 0.7856604788 3.70512237 
2806  519.7277 1.6199604788 16.06512237 
2807  528.9377 2.2416354788 25.27512237 
2808  520.2677 1.6564104788 16.60512237 
2809  519.3877 0.5355647187 0.00000000 
2810  526.5677 2.0816604788 22.90512237 
2811  519.5377 0.5355647187 0.00000000 
2812  526.9277 2.1059604788 23.26512237 
2813  529.9877 2.3125104788 26.32512237 
2814  514.4077 1.2608604788 10.74512237 
2815  518.3777 1.5288354788 14.71512237 

sto cercando di identificare i valori negativi rgdeltas [per esempio, la riga 2804] e poi 'look' 7 posizioni dietro e davanti per trovare il Tempadjvolt più alto e impostare il tempadjvolt della riga 2804 su quel massimo locale.

Il frame è lungo ~ 4000 righe, di cui ~ 515 sono valori negativi. Ho provato un paio di cicli che hanno funzionato ... ma anche sputare un mucchio di NA, il che mi fa pensare che siano stati costruiti male/impropriamente.

Qualsiasi assistenza sarebbe molto apprezzata.

Come è stato sottolineato nei commenti, il post originale non era chiaro. Non sono preoccupato per i valori negativi di rgdeltas negativi. Per i valori negativi all'interno di 7 del fronte e della fine del frame, idealmente il loop dovrebbe apparire come molte posizioni avanti e indietro prima dell'inizio/fine. Meno preoccupato di questo a questo punto.

Un po 'più di fondo: Questo fa parte di un programma di elaborazione del segnale originariamente scritto in C# che sto tentando di passare a R per aumentare un po' più facile l'elaborazione in batch di un gran numero di uscita file da un monitor ambientale. Non ho scritto il codice originale e questo è solo un piccolo componente di un insieme molto più ampio di cose in corso.

Apprezzo l'aiuto. Grazie!

+0

non credo la domanda ha una risposta univoca. Non hai offerto una soluzione a ciò che accade se due valori negativi si trovano entro 14 posizioni l'una dall'altra, come chiaramente sono in alcuni casi. (... o forse ho frainteso la nozione di reimpostazione a "linea di base" –

+0

Né hai specificato cosa dovrebbe accadere se un valore negativo è inferiore a 7 righe dall'inizio o alla fine.Subito sospetto che potrebbe essere la fonte del tuo NAs – joran

+0

Dwin, joran - grazie, ho pubblicato una povera rappresentazione dei miei dati sopra, che sto per risolvere, non mi preoccupo di due o più negativi in ​​un tratto l'uno dell'altro.Se il valore è all'inizio o alla fine ... non ci ho pensato. Mi scuso per l'ambiguità, speriamo che le mie modifiche in un minuto aiuteranno. –

risposta

4

assumere il suo nome è dat:

negidxs <- as.numeric(rownames(dat)[ dat[[3]] < 0 ]) 
for (i in negidxs){ 
     dat[as.character(i), "Tempadjvolt"] <- 
      max(dat[rownames(dat) %in% (i-7):(i+7), "Tempadjvolt"], na.rm=TRUE) } 
dat 
    #----------------------------------# 
    Tempadjvolt newmass rgdeltas 
2794 498.5777 0.5355647 0.000000 
2795 499.7577 0.5355647 0.000000 
2796 517.8877 0.3415105 -2.874878 
2797 517.8877 0.4312855 -1.544878 
2798 500.3877 0.5355647 0.000000 
2799 519.7277 0.4596355 -1.124878 
2800 507.6877 0.8072605 4.025122 
2801 505.2577 0.6432355 1.595122 
2802 505.7977 0.6796855 2.135122 
#snipped----- 
5

1) Zero Fill. Supponendo che il frame di dati è chiamato DF usiamo rollapply nel pacchetto zoo per applicare la funzione, f, ad una finestra mobile di larghezza 15:

library(zoo) 
# columns of DF are (1) Tempadjvolt, (2) newmass and (3) rgdeltas 
f <- function(x) if (x[8, 3] < 0) max(x[, 1]) else x[8, 1] 
DF[[1]] <- rollapply(DF, 15, f, fill = 0, by.column = FALSE) 

In precedenza abbiamo riempito i punti vicino all'inizio e alla fine con zeri poiché sembra che il modo preciso di affrontare questo non sia così importante, ma avremmo potuto usare qualche altro valore di riempimento.

2) Lasciare valori finali. Un'altra possibilità è quella di elaborare solo i punti non vicino alle estremità:

DF[seq(8, nrow(DF)-7), 1] <- rollapply(DF, 15, f, by.column = FALSE) 

3) partial. o avremmo potuto utilizzare partial = TRUE e poi prendere il max dei valori parziali vicino alle estremità di questo tipo:

f2 <- function(x) { 
     # Columns of DF2 are (1) Tempadjvolt, (2) newmass, (3) rgdeltas and (4) seq. 
     # Condition is TRUE if passed a partial x near the beginning. 
     # k is row index of current row in x. Normally 8 but near start it varies. 
     k <- if (x[1, 4] == 1) nrow(x) - 7 else 8 
     if (x[k, 3] < 0) max(x[, 1]) else x[k, 1] 
} 
DF2 <- cbind(DF, seq = 1:nrow(DF)) 
DF[[1]] <- rollapply(DF2, 15, f2, partial = TRUE, by.column = FALSE)