Вот ваниль 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
.
[Отредактировано решение немного, поскольку производительность не держат на больших векторов (это делает сейчас).]
что это ближайшая средняя значит? – Alex
Почему вы хотите это сделать? Какова связь между столбцами? Какова связь между рядами? Я спрашиваю, потому что маловероятно, что вы хотите делать то, что, по вашему мнению, хотите сделать. – John