2014-10-29 3 views
0

У меня есть несколько столбцов, как это:отсутствующего значение вменения в г

0.277289310 
0.275562150 
0.265427900 
NA 
0.259514200 
0.277133810 
NA 

NA является случайным, я хочу использовать ближайшие средний вменяю NA, если это последний затем использовать предыдущее значение. Как мне это сделать?

+1

что это ближайшая средняя значит? – Alex

+0

Почему вы хотите это сделать? Какова связь между столбцами? Какова связь между рядами? Я спрашиваю, потому что маловероятно, что вы хотите делать то, что, по вашему мнению, хотите сделать. – John

ответ

4

Вот ваниль R решение, которое более чем в 2 раза быстрее, чем решение Ричарда.

vec <- c(NA, 0.277289310, 0.275562150, NA, 0.265427900, NA, NA, NA, 0.259514200, 0.277133810, NA) 

ups <- c(if (is.na(vec[1])) NA else NULL, which(c(diff(is.na(vec))) == 1)) 
downs <- c(which(c(0, diff(is.na(vec))) == -1), if (is.na(tail(vec, 1))) NA else NULL) 
narle <- rle(is.na(vec)) 

vec[is.na(vec)] <- rep((vec[ups] + vec[downs])/2, narle$lengths[narle$values]) 
if (is.na(ups[1])) vec[seq_len(downs[1] - 1)] <- vec[downs[1]] 
if (is.na(tail(downs, 1))) vec[tail(ups, 1):length(vec)] <- vec[tail(ups, 1)] 

# [1] 0.2772893 0.2772893 0.2755622 0.2704950 0.2654279 0.2624710 0.2624710 0.2624710 0.25951420.2771338 0.2771338 

Некоторые тесты:

# > microbenchmark(richard_srivens_solution(vec), my_solution(vec)) 
# Unit: microseconds 
#       expr  min  lq median  uq  max neval 
# richard_srivens_solution(vec) 262.232 315.6010 501.4830 519.6025 2146.601 100 
#    my_solution(vec) 98.891 141.5545 201.0715 213.7605 714.621 100 

Если вы хотите немного больше объяснений, продолжайте чтение. Сердцем этого являются два заявления which(diff(is.na(vec)) == 1) и which(c(0, diff(is.na(vec))) == -1), которые дают (для вышеуказанных vec) значения c(3,5,10) и c(2,5,9), соответственно. Другими словами, это позиции переходов от не-NA к NA и переход от NA к не-NA соответственно.

Если вы думаете об этом в течение нескольких минут, вы увидите, что это все, что нам нужно: мы можем просто усреднять пары этих значений (слегка заботясь о конечных точках) и назначать их отсутствующие значения исходного вектора. Нам нужно только быть осторожным, чтобы воспроизвести эти средние значения для последовательных последовательностей отсутствующих значений. Но это можно выполнить с помощью функции rle.

[Отредактировано решение немного, поскольку производительность не держат на больших векторов (это делает сейчас).]

2

Попробуйте сочетание na.approx и na.locf из zoo пакета

x <- c(0.27728931, 0.27556215, 0.2654279, NA, 0.2595142, 0.27713381, NA) 
library(zoo) 
na.locf(na.approx(x, na.rm=FALSE)) 
# [1] 0.2772893 0.2755622 0.2654279 0.2624710 0.2595142 0.2771338 0.2771338 
0

Try:

xx 
[1] 0.2755622 0.2654279  NA 0.2595142 0.2771338  NA 

for(i in 1:length(xx)) if(is.na(xx[i])) 
     xx[i] = ifelse(is.na(xx[i+1]),  xx[i-1], (xx[i-1]+xx[i+1])/2) 

xx 
[1] 0.2755622 0.2654279 0.2624710 0.2595142 0.2771338 0.2771338 
+0

Используя пример @Robert Krzyzanowski 'vec', я получаю другой результат, используя ваш код. – akrun

+0

Да, это не ищет цепочки 'NA's –

+0

Изменен код выше. – rnso

Смежные вопросы