簡體   English   中英

在 R 中使用循環用均值替換 NA

[英]Replacing NA with mean using loop in R

我必須在 R 中使用循環來解決這個問題(我知道沒有循環你可以更容易地做到這一點,但它是為了學校......)。

所以我有這樣的 NA 向量:

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

我必須創建一個 FOR 循環,它將用 NA 之前的 2 個數字和 NA 之后的 2 個數字的平均值替換 NA。

這是我能夠做到的,循環如下:

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,那么您必須用 4 個前面的數字和后面的 4 個數字的平均值替換 NA(我假設刪除了 NA)。 但我就是無法破解它......我用這個循環獲得了最好的結果:

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。

提前謝謝你的幫助。

我們可以使用zoo na.approx

library(zoo)
na.approx(trades)

所以似乎發布到 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

如果你運行這個循環:

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

所以它幾乎按預期工作。

謝謝你的幫助。

這是使用循環的另一種解決方案。 我通過使用dplyr leadlag dplyr一些代碼。 首先,我們使用 2 個遞歸函數來計算超前和滯后總和。 然后我們使用條件語句來確定是否有任何缺失的數據。 最后,我們使用遞歸的輸出或前后 4 的總和(去除 NA)來填充缺失的數據。 我會注意到這不是我解決這個問題的方式,但我按照要求用循環進行了嘗試。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM