Интерполировать значения NA в кадре данных с помощью na.approx - PullRequest
17 голосов
/ 06 сентября 2011

Я пытаюсь удалить NA s из моего фрейма данных путем интерполяции с na.approx(), но не могу удалить все NA s.

Мой фрейм данных - 4096x4096 с 270,15 какфлаг для недопустимого значения.Мне нужны данные, чтобы быть непрерывными во всех точках, чтобы обеспечить метеорологическую модель.Вчера я спросил и получил ответ о том, как заменить значения во фрейме данных на основе другого фрейма данных.Но после этого я пришел к na.approx(), а затем решил заменить значения 270,15 на NA и попробовать na.approx() для интерполяции данных.Но вопрос в том, почему na.approx() не заменяет все NA.

Вот что я делаю:

  • Считайте оригинальный hdf-файл с hdf5load
  • Subsetкадр данных (4094x4096)
  • Заменить значение флага на NA

    > sst4[sst4 == 270.15 ] = NA
    
  • Проверить первый столбец (или любой другой)

    > 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
    
  • Запустить na.approx

    > sst4=na.approx(sst4,na.rm="FALSE")
    
  • Проверить первый столбец

    > 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
    

Как вы видите 411АН не были удалены.Зачем?Все ли они соответствуют начальным / конечным значениям столбца?

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

Нужно ли na.approx иметь допустимые значения до и после NA для интерполяции?Нужно ли устанавливать какой-либо другой параметр na.approx?

Большое спасибо

Ответы [ 3 ]

13 голосов
/ 06 сентября 2011

Небольшой воспроизводимый пример:

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

Да, похоже, вам нужны начальные / конечные значения столбцов, или интерполяция не работает.Можете ли вы угадать значения для ваших границ?

ДРУГОЕ РЕДАКТИРОВАНИЕ: Таким образом, по умолчанию вам нужно знать начальное и конечное значения столбцов.Однако можно получить na.approx, чтобы всегда заполнять пробелы, передавая rule = 2.Смотрите ответ Феликса.Вы также можете использовать na.fill для предоставления значения по умолчанию, согласно комментарию Габора.Наконец, вы можете интерполировать граничные условия в двух направлениях (см. Ниже) или угадывать граничные условия.


РЕДАКТИРОВАТЬ: Дополнительная мысль.Поскольку na.approx интерполируется только по столбцам, а ваши данные пространственны, возможно, интерполяция по строкам также будет полезна.Тогда вы могли бы взять среднее значение.

na.approx терпит неудачу, когда целые столбцы равны NA, поэтому мы создаем больший набор данных.

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

Запуск na.approx в обе стороны.

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

Узнайте лучшие догадки.

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
  )
)
10 голосов
/ 06 сентября 2011

na.approx() следует за функцией approx() только при интерполяции значений, не экстраполируя их по умолчанию.Однако, как описано на странице справки для approx(), вы можете указать rule = 2 для экстраполяции в качестве постоянного значения ближайшего экстремума.Исходя из примера Ричи Коттона:

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

Эквивалентно, вы можете явно использовать «перенос последнего наблюдения».

na.locf(na.approx(m))
## "first observation carry backwards" too:
na.locf(na.locf(na.approx(m)), fromLast = TRUE)
1 голос
/ 06 сентября 2011

Я думаю, вы должны попытаться установить na.rm=TRUE

Из документов

на.рм логично. Должны ли быть удалены ведущие НС?

http://www.oga -lab.net / RGM2 / func.php rd_id = зоопарк: na.approx

...