Интерполировать значения NA во фрейме данных с помощью na.approx

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

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

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

  • Прочтите исходный файл hdf с помощью hdf5load
  • Подмножество фрейма данных (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 NA не были удалены. Почему? Все ли они соответствуют значениям ведущего / конечного столбца?

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?

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


person pacomet    schedule 06.09.2011    source источник


Ответы (3)


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

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
  )
)
person Richie Cotton    schedule 06.09.2011
comment
Спасибо, Ричи. Я попробую угадать значения границ; так как пространственное расширение моей базы данных sst намного больше, чем предметная область модели, которую я буду использовать, я не особо беспокоюсь о значениях на границах. На самом деле мне нужно заполнить значения NA в центральной области фрейма данных. - person pacomet; 06.09.2011
comment
Кто бы ни проголосовал за меня, не могли бы вы оставить комментарий, объяснив, что вам не понравилось. Если вы не предоставите отзыв, я не смогу улучшить ответ. - person Richie Cotton; 06.09.2011
comment
-1 неверно, что вам нужны начальные и конечные значения. Конечные точки могут быть расширены, как в ответе Феликса или в na.fill. - person G. Grothendieck; 06.09.2011
comment
Привет, в данном случае я не думаю, что это необходимо, но я могу попробовать поискать результаты. Спасибо, ваш ответ был для меня правильным. - person pacomet; 06.09.2011
comment
@ГРАММ. Гротендик: Точка взята; уточнили ответ. - person Richie Cotton; 06.09.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)
person Felix Andrews    schedule 06.09.2011
comment
Спасибо за Ваш ответ. Он работает, но, возможно, не подходит для моих данных. Поскольку данные представляют собой температуру поверхности моря, возможно, не стоит экстраполировать как постоянное значение в случае, если данные NA находятся над морем (хотя большинство случаев NA относятся к точкам суши), где вы обычно находите плавный переход между точками сетки. - person pacomet; 06.09.2011
comment
na.approx(... rule=2) великолепно недокументирован на странице руководства! Он похоронен в 70-страничном PDF-документе. - person smci; 15.04.2015

Думаю, стоит попробовать установить na.rm=TRUE

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

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

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

person Henrik    schedule 06.09.2011
comment
Привет, Хенрик. Если я установил na.rm = TRUE, то я получаю фрейм данных 3818x4096, и мне нужно сохранить все значения 4096x4096. - person pacomet; 06.09.2011
comment
Хм, а как насчет того, чтобы пропустить причудливую интерполяцию и сделать простой цикл, который при просмотре NA копирует последнее значение, отличное от NA? - person Henrik; 06.09.2011
comment
Я новичок в R, и мне придется искать синтаксис цикла, я пытаюсь справиться с базовыми командами. Как мне сохранить последнее значение, отличное от NA? Что произойдет, если первое значение в столбце - NA? Также я предпочитаю плавный переход между значениями данных. Это значения температуры поверхности моря, а НА - точки над сушей, где для модели требуются реалистичные значения, чтобы избежать численных проблем при решении уравнений. Спасибо за ваше предложение. - person pacomet; 06.09.2011
comment
Я понимаю вашу проблему, но полагаю, что это будет не очень точная температура земли, если вы интерполируете из SST. Может быть, взгляните на обратную взвешенную интерполяцию по расстоянию и представьте, что ваши данные SST являются точечными измерениями ?? - person Henrik; 06.09.2011
comment
Я не беспокоюсь о точности, потому что модель знает, где находятся точки суши / моря, и ей просто нужен плавный переход. Но я буду искать обратную взвешенную интерполяцию по расстоянию. Спасибо. - person pacomet; 06.09.2011
comment
Ссылка не работает. - person zx8754; 08.08.2019