Замена NA на среднее с использованием l oop в R - PullRequest
1 голос
/ 05 января 2020

Я должен решить эту проблему, используя l oop в R (я знаю, что вы можете сделать это намного проще без циклов, но это для школы ...).

Так что у меня есть вектор с NA следующим образом:

trades<-sample(1:500,150,T)
trades<-trades[order(trades)]
trades[sample(10:140,25)]<-NA

, и мне нужно создать FOR l oop, который заменит NA на среднее от 2 чисел до NA и 2 чисел, следующих за NA.

Это я могу сделать с l oop вот так:

for (i in 1:length(trades)) {
  if (is.na(trades[i])==T) {

      trades[i] <- mean(c(trades[c(i-1:2)], trades[c(i+1:2)]), na.rm = T)
     }
  }

Но есть и другая часть домашней работы. Если в 2 предыдущих или 2 следующих числах есть NA, то вы должны заменить NA средним значением из 4 предыдущих и 4 следующих чисел (я предполагаю, что удаление NA). Но я просто не могу его взломать ... У меня лучшие результаты с этим l oop:

for (i in 1:length(trades)) {
  if (is.na(trades[i])==T && is.na(trades[c(i-1:2)]==T || is.na(trades[c(i+1:2)]==T))) {
   trades[i] <- mean(c(trades[c(i-1:4)], trades[c(i+1:4)]), na.rm = T)
  }else if (is.na(trades[i])==T){
    trades[i] <- mean(c(trades[c(i-1:2)], trades[c(i+1:2)]))
  }

}

Но он все еще пропускает некоторые NA.

Спасибо за ваш помогите заранее.

Ответы [ 3 ]

2 голосов
/ 05 января 2020

Мы можем использовать na.approx от zoo

library(zoo)
na.approx(trades)
1 голос
/ 06 января 2020

Вот еще одно решение, использующее al oop. Я сделал ярлык некоторого кода, используя lead и lag из dplyr. Сначала мы используем 2 рекурсивные функции для вычисления опережающих и запаздывающих сумм. Затем мы используем условные операторы, чтобы определить, есть ли пропущенные данные. Наконец, мы заполняем недостающие данные, используя либо выход рекурсивного, либо сумму предыдущих и последующих 4 (с удалением NA). Я хотел бы отметить, что это не тот способ, которым я бы go об этой проблеме, но я попробовал это с al oop в соответствии с просьбой.

library(dplyr)

r.lag <- function(x, n){
  if (n == 1) return(lag(x = x, n = 1))
  else return( lag(x = x, n = n) +  r.lag(x = x, n = n-1))
}

r.lead <- function(x, n){
  if (n == 1) return(lead(x = x, n = 1))
  else return( lead(x = x, n = n) +  r.lead(x = x, n = n-1))
}

lead.vec <- r.lead(trades, 2)
lag.vec <- r.lag(trades, 2)

output <- vector(length = length(trades))
for(i in 1:length(trades)){
  if(!is.na(trades[[i]])){
    output[[i]] <- trades[[i]]
  }
  else if(is.na(trades[[i]]) & !is.na(lead.vec[[i]]) & !is.na(lag.vec[[i]])){
    output[[i]] <- (lead.vec[[i]] + lag.vec[[i]])/4
  }
  else
    output[[i]] <- mean(
      c(trades[[i-4]], trades[[i-3]], trades[[i-2]], trades[[i-1]], 
        trades[[i+4]], trades[[i+3]], trades[[i+2]], trades[[i+1]]),
      na.rm = T
      )
}

tibble(
  original = trades,
  filled = output
)
#> # A tibble: 150 x 2
#>    original filled
#>       <int>  <dbl>
#>  1        7      7
#>  2        7      7
#>  3       12     12
#>  4       18     18
#>  5       30     30
#>  6       31     31
#>  7       36     36
#>  8       NA     40
#>  9       43     43
#> 10       50     50
#> # … with 140 more rows
1 голос
/ 05 января 2020

Так что, похоже, что публикация в StackOverflow помогла мне решить проблему.

trades<-sample(1:500,25,T)
trades<-trades[order(trades)]
trades[sample(1:25,5)]<-NA

, что дает нам:

[1]  NA  20  24  30  NA  77 188 217 238 252 264 273 296  NA 326 346 362 368  NA  NA 432 451 465 465 490

и если вы запустите это l oop:

for (i in 1:length(trades)) {
  if (is.na(trades[i])== T) {
    test1 <- c(trades[c(i+1:2)])
       if (any(is.na(test1))==T) {
        test2 <- c(trades[abs(c(i-1:4))], trades[c(i+1:4)])
        trades[i] <- round(mean(test2, na.rm = T),0)
      }else {
        test3 <- c(trades[abs(c(i-1:2))], trades[c(i+1:2)])
        trades[i] <- round(mean(test3, na.rm = T),0)
      }
    }
  }

меняет NA следующим образом:

[1]  22  20  24  30  80  77 188 217 238 252 264 273 296 310 326 346 362 368 387 410 432 451 465 465 490

Так что все работает почти так, как ожидалось.

Спасибо за вашу помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...