2011-09-06 15 views
17

Próbuję usunąć NA s z mojej ramki danych przez interpolację z na.approx(), ale nie można usunąć wszystkich NA s.Interpoluj wartości NA w ramce danych z na.approx

Moja ramka danych to 4096 x 4096 z 270,15 jako flagą dla nieprawidłowej wartości. Potrzebuję danych, aby były ciągłe we wszystkich punktach, aby wyżywić model meteorologiczny. Wczoraj zapytałem i otrzymałem odpowiedź, jak zastąpić wartości w ramce danych w innej ramce danych. Ale potem przyszedł do na.approx(), a następnie postanowił zastąpić wartości 270.15 z NA i spróbuj na.approx() interpolować dane. Ale pytanie brzmi: dlaczego na.approx() nie zastępuje wszystkich NA.

To co robie:

  • Czytaj oryginalny plik HDF z hdf5load
  • podzbiór ramki danych (4094x4096)
  • zastępczy wartość flagi z NA

    > sst4[sst4 == 270.15 ] = NA 
    
  • Sprawdź pierwszą kolumnę (lub dowolną inną)

    > summary(sst4[,1]) 
    
    Min. 1st Qu. Median Mean 3rd Qu. Max. NA's 
    271.3 276.4 285.9 285.5 292.3 302.8 1345.0 
    
  • Run na.approx

    > sst4=na.approx(sst4,na.rm="FALSE") 
    
  • Sprawdź Pierwsza kolumna

    > summary(sst4[,1]) 
    Min. 1st Qu. Median Mean 3rd Qu. Max. NA's 
    271.3 276.5 286.3 285.9 292.6 302.8 411.0 
    

Jak widać 411 NA nie zostały usunięte. Czemu? Czy wszystkie odpowiadają wartościom wiodącym/końcowym kolumny?

head(sst4[,1]) 
[1] NA NA NA NA NA NA 
tail(sst4[,1]) 
[1] NA NA NA NA NA NA 

Czy na .approx potrzebne są prawidłowe wartości przed i po interpolacji NA? Czy muszę ustawić inną opcję na.approx?

Dziękuję bardzo

Odpowiedz

12

małe, powtarzalne przykład:

library(zoo) 
set.seed(1) 
m <- matrix(runif(16, 0, 100), nrow = 4) 
missing_values <- sample(16, 7) 
m[missing_values] <- NA 
m 
     [,1]  [,2]  [,3]  [,4] 
[1,] 26.55087 20.16819 62.911404 68.70228 
[2,] 37.21239  NA 6.178627 38.41037 
[3,]  NA  NA  NA  NA 
[4,] 90.82078 66.07978  NA  NA 

na.approx(m) 
     [,1]  [,2]  [,3]  [,4] 
[1,] 26.55087 20.16819 62.911404 68.70228 
[2,] 37.21239 35.47206 6.178627 38.41037 
[3,] 64.01658 50.77592  NA  NA 
[4,] 90.82078 66.07978  NA  NA 

m[4, 4] <- 50 
na.approx(m) 
     [,1]  [,2]  [,3]  [,4] 
[1,] 26.55087 20.16819 62.911404 68.70228 
[2,] 37.21239 35.47206 6.178627 38.41037 
[3,] 64.01658 50.77592  NA 44.20519 
[4,] 90.82078 66.07978  NA 50.00000 

Tak, wygląda na to, że potrzebujemy wartości Początek/Koniec kolumny mają być znane lub interpolacja nie działa. Czy potrafisz odgadnąć wartości dla swoich granic?

KOLEJNA EDYCJA: Domyślnie potrzebne są początkowe i końcowe wartości kolumn. Jednak możliwe jest uzyskanie na.approx, aby zawsze wypełniać puste pola, przekazując rule = 2. Zobacz odpowiedź Feliksa. Możesz także użyć wartości na.fill, aby podać wartość domyślną, zgodnie z komentarzem Gabora.Na koniec można interpolować warunki brzegowe w dwóch kierunkach (patrz poniżej) lub odgadnąć warunki brzegowe.


EDYCJA: Kolejna myśl. Ponieważ na.approx interpoluje tylko w kolumnach, a twoje dane są przestrzenne, może się przydać interpolacja w wierszach. Wtedy możesz wziąć średnią.

na.approx kończy się niepowodzeniem, gdy całe kolumny są NA, więc tworzymy większy zbiór danych.

set.seed(1) 
m <- matrix(runif(64, 0, 100), nrow = 8) 
missing_values <- sample(64, 15) 
m[missing_values] <- NA 

Uruchom na.approx w obie strony.

by_col <- na.approx(m) 
by_row <- t(na.approx(t(m))) 

Dowiedz się, jak najlepiej odgadnąć.

default <- 50 
best_guess <- ifelse(is.na(by_row), 
    ifelse(
    is.na(by_col), 
    default,    #neither known 
    by_col    #only by_col known 
), 
    ifelse(
    is.na(by_col), 
    by_row,    #only by_row known 
    (by_row + by_col)/2 #both known 
) 
) 
+0

Dzięki Richie. Spróbuję odgadnąć wartości dla granic; ponieważ przestrzenne rozszerzenie mojej bazy danych jest znacznie większe niż domena modelu, z której będę korzystał, nie martwię się specjalnie o wartości na granicach. To, czego potrzebuję, to wypełnić wartości NA w centralnym regionie ramki danych. – pacomet

+0

Ktokolwiek mnie zawiódł, proszę zostaw komentarz wyjaśniający, co ci się nie podobało. Jeśli nie dostarczysz opinii, nie będę mógł poprawić odpowiedzi. –

+0

-1 Nieprawda, że ​​potrzebujesz wartości początkowej i końcowej. Punkty końcowe można rozszerzyć jak w odpowiedzi Feliksa lub w "na.fill". –

1

myślę, że należy spróbować ustawić na.rm=TRUE

Od docs

na.rm logicznych. Czy wiodące NA mają zostać usunięte?

http://www.oga-lab.net/RGM2/func.php?rd_id=zoo:na.approx

+0

Cześć Henrik. Jeśli ustawię na.rm = TRUE, otrzymam ramkę danych 3818x4096 i muszę zachować wszystkie wartości 4096x4096. – pacomet

+0

Hmm, a może pominąć fantazyjną interpolację i zrobić prostą pętlę, która po zobaczeniu NA skopiuje ostatnią wartość inną niż NA? – Henrik

+0

Jestem nowy dla R i będę musiał szukać składni pętli, próbuję zarządzać za pomocą podstawowych poleceń. Jak zachować ostatnią wartość inną niż NA? Co się stanie, jeśli pierwszą wartością w kolumnie będzie NA? Ponadto wolę płynne przejście między wartościami danych. Są to wartości temperatury powierzchni morza, a NA to punkty na lądzie, gdzie model spełnia "realistyczne" wartości, aby uniknąć problemów numerycznych przy rozwiązywaniu równań. Dzięki za Twoją sugestię. – pacomet

9

na.approx() następuje tylko funkcję interpolacji wartości, a nie ich ekstrapolację domyślnie approx(). Jednak, jak opisano na stronie pomocy dla approx(), możesz określić rule = 2, aby ekstrapolować jako stałą wartość najbliższej skrajności. W następstwie przykładu Richie Cotton:

na.approx(m, rule = 2) 
     [,1]  [,2]  [,3]  [,4] 
[1,] 26.55087 20.16819 62.911404 68.70228 
[2,] 37.21239 35.47206 6.178627 38.41037 
[3,] 64.01658 50.77592 6.178627 38.41037 
[4,] 90.82078 66.07978 6.178627 38.41037 

Równolegle można użyć "ostatniej obserwacji przeniesienia" jawnie.

na.locf(na.approx(m)) 
## "first observation carry backwards" too: 
na.locf(na.locf(na.approx(m)), fromLast = TRUE) 
+0

Dzięki za odpowiedź. To działa, ale może nie jest dobre dla moich danych. Jako że dane są temperaturą powierzchni morza, być może nie jest dobrym pomysłem ekstrapolacja jako stała wartość w przypadku, gdy dane NA są nad morzem (chociaż większość przypadków NA dotyczy punktów lądowych), gdzie zwykle znajduje się płynne przejście między punktami siatki. – pacomet

+0

'na.approx (... rule = 2)' jest chwalebnie nieudokumentowane na stronie podręcznika! Jest pochowany w 70-stronicowym dokumencie PDF. – smci