2012-07-18 6 views
7

Sto cercando di implementare il filtro Chebyshev per arrotondare una serie temporale, ma sfortunatamente ci sono NA nella serie di dati.R() che si occupa di NA

Per esempio,

t <- seq(0, 1, len = 100)      
x <- c(sin(2*pi*t*2.3) + 0.25*rnorm(length(t)),NA, cos(2*pi*t*2.3) + 0.25*rnorm(length(t))) 

Sto usando il filtro di Chebyshev: cf1 = cheby1(5, 3, 1/44, type = "low")

Sto cercando di filtrare il tempo di serie escludono AN, ma non rovinare l'ordini/posizione. Quindi, ho già provato na.rm=T, ma sembra che non ci sia tale argomento. Quindi

z <- filter(cf1, x) # apply filter 

Grazie ragazzi.

risposta

1

È possibile rimuovere preventivamente le NA utilizzando la funzione compelete.cases. Potresti anche considerare di imputare i dati mancanti. Controlla i pacchetti mtsdi o Amelia II.

EDIT:

Ecco una soluzione con Rcpp. Questo potrebbe essere utile è la velocità è importante:

require(inline) 
require(Rcpp) 
t <- seq(0, 1, len = 100) 
set.seed(7337) 
x <- c(sin(2*pi*t*2.3) + 0.25*rnorm(length(t)),NA, cos(2*pi*t*2.3) + 0.25*rnorm(length(t))) 
NAs <- x 
x2 <- x[!is.na(x)] 
#do something to x2 
src <- ' 
Rcpp::NumericVector vecX(vx); 
Rcpp::NumericVector vecNA(vNA); 
int j = 0; //counter for vx 
for (int i=0;i<vecNA.size();i++) { 
    if (!(R_IsNA(vecNA[i]))) { 
    //replace and update j 
    vecNA[i] = vecX[j]; 
    j++; 
    } 
} 
return Rcpp::wrap(vecNA); 
' 
fun <- cxxfunction(signature(vx="numeric", 
          vNA="numeric"), 
        src,plugin="Rcpp") 
if (identical(x,fun(x2,NAs))) 
    print("worked") 
# [1] "worked" 
+0

Mi chiedo solo se il file complete.case è lo stesso di na.omit. Inoltre, dal momento che sto usando le serie temporali SST osservate, non sono sicuro se sia una buona idea inserire i valori mancanti. –

+0

Speriamo che questo aggiornamento risolva il problema. – chandler

2

Provare a utilizzare x <- x[!is.na(x)] per rimuovere gli AN, quindi eseguire il filtro.

+0

scusate, ma se uso na.omit, ammasserà gli ordini, voglio solo il valore di NA dopo che il filtro rimane NA, ma tutti gli altri valori non NA possono passare. –

+0

Scusa, non sono sicuro di cosa stai chiedendo. Vuoi mantenere i tuoi valori nella stessa posizione e avere spazi nei tuoi dati? –

+0

na.remove() o na.remove.ts() dal pacchetto tseries fanno ciò che si desidera? –

1

Non so se ts oggetti possono avere valori mancanti, ma se si desidera solo per re-inserire i valori NA, è possibile utilizzare ?insert da R.utils. Potrebbe esserci un modo migliore per farlo.

install.packages(c('R.utils', 'signal')) 
require(R.utils) 
require(signal) 
t <- seq(0, 1, len = 100)      
set.seed(7337) 
x <- c(sin(2*pi*t*2.3) + 0.25*rnorm(length(t)), NA, NA, cos(2*pi*t*2.3) + 0.25*rnorm(length(t)), NA) 
cf1 = cheby1(5, 3, 1/44, type = "low") 
xex <- na.omit(x) 
z <- filter(cf1, xex) # apply 
z <- as.numeric(z) 
for (m in attributes(xex)$na.action) { 
    z <- insert(z, ats = m, values = NA) 
} 
all.equal(is.na(z), is.na(x)) 
?insert 
0

Ecco una funzione che è possibile utilizzare per filtrare un segnale con NA in esso. Le NA vengono ignorate anziché sostituite da zero.

È quindi possibile specificare una percentuale massima di peso che gli NA possono assumere in qualsiasi punto del segnale filtrato. Se ci sono troppe NA (e troppi pochi dati effettivi) in un punto specifico, il segnale filtrato stesso verrà impostato su NA.

# This function applies a filter to a time series with potentially missing data 

filter_with_NA <- function(x, 
          window_length=12,       # will be applied centrally 
          myfilter=rep(1/window_length,window_length), # a boxcar filter by default 
          max_percentage_NA=25)      # which percentage of weight created by NA should not be exceeded 
{ 
    # make the signal longer at both sides 
    signal <- c(rep(NA,window_length),x,rep(NA,window_length)) 
    # see where data are present and not NA 
    present <- is.finite(signal) 

    # replace the NA values by zero 
    signal[!is.finite(signal)] <- 0 
    # apply the filter 
    filtered_signal <- as.numeric(filter(signal,myfilter, sides=2)) 

    # find out which percentage of the filtered signal was created by non-NA values 
    # this is easy because the filter is linear 
    original_weight <- as.numeric(filter(present,myfilter, sides=2)) 
    # where this is lower than one, the signal is now artificially smaller 
    # because we added zeros - compensate that 
    filtered_signal <- filtered_signal/original_weight 
    # but where there are too few values present, discard the signal 
    filtered_signal[100*(1-original_weight) > max_percentage_NA] <- NA 

    # cut away the padding to left and right which we previously inserted 
    filtered_signal <- filtered_signal[((window_length+1):(window_length+length(x)))] 
    return(filtered_signal) 
}