【问题标题】:Replace row of NAs with previous row in R用 R 中的前一行替换 NA 行
【发布时间】:2013-01-25 09:49:21
【问题描述】:

我想知道是否有人对以下问题有快速而肮脏的解决方案,我有一个包含 NA 行的矩阵,我想用前一行替换 NA 行(如果它不是一行NA)。

假设第一行不是一行 NAs

谢谢!

【问题讨论】:

  • 看看na.locf 来自zoo 包。
  • 我以为他说他不想填写多个 NA?

标签: r matrix na


【解决方案1】:

改编自对这个问题的回答:Idiomatic way to copy cell values "down" in an R vector

f <- function(x) {
  idx <- !apply(is.na(x), 1, all)
  x[idx,][cumsum(idx),]
}

x <- data.frame(a=c(1, 2, NA, 3, NA, NA), b=c(4, 5, NA, 6, NA, 7))

> x
   a  b
1  1  4
2  2  5
3 NA NA
4  3  6
5 NA NA
6 NA  7

> f(x)
     a b
1    1 4
2    2 5
2.1  2 5
4    3 6
4.1  3 6
6   NA 7

【讨论】:

    【解决方案2】:

    试想一下,您可能会连续有两行全部为 NA 的行。

    #create a data set like you discuss (in the future please do this yourself)
    set.seed(14)
    x <- matrix(rnorm(10), nrow=2)
    y <- rep(NA, 5)
    v <- do.call(rbind.data.frame, sample(list(x, x, y), 10, TRUE))
    

    一种方法:

    NArows <- which(apply(v, 1, function(x) all(is.na(x))))          #find all NAs
    notNA <- which(!seq_len(nrow(v)) %in% NArows)                    #find non NA rows
    rep.row <- sapply(NArows, function(x) tail(notNA[x > notNA], 1)) #replacement rows
    v[NArows, ] <- v[rep.row, ]                                      #assign
    v                                                                #view              
    

    如果您的第一行都是 NA,这将不起作用。

    【讨论】:

      【解决方案3】:

      你总是可以使用循环,这里假设 1 不是 NA 所示:

      fill = data.frame(x=c(1,NA,3,4,5))
      for (i in 2:length(fill)){
        if(is.na(fill[i,1])){ fill[i,1] = fill[(i-1),1]}
       }
      

      【讨论】:

        【解决方案4】:

        如果m 是您的矩阵,这是您的快速解决方案:

        sapply(2:nrow(m),function(i){ if(is.na(m[i,1])) {m[i,] <<- m[(i-1),] } })
        

        请注意,它使用了丑陋(且危险)的 &lt;&lt;- 运算符。

        【讨论】:

        • &lt;&lt;- 在传递给sapply 的函数中意味着您应该使用for 循环(或完全不同的方法)。
        【解决方案5】:

        马修的例子:

        x <- data.frame(a=c(1, 2, NA, 3, NA, NA), b=c(4, 5, NA, 6, NA, 7))
         na.rows <- which( apply( x , 1, function(z) (all(is.na(z)) ) ) )
         x[na.rows , ] <- x[na.rows-1, ]
         x
        #---
           a b
        1  1 4
        2  2 5
        3  2 5
        4  3 6
        5  3 6
        6 NA 7
        

        显然,所有 NA 的第一行都会出现问题。

        【讨论】:

          【解决方案6】:

          这是一个简单明了的概念,也许是最简单的单线:

          x <- data.frame(a=c(1, 2, NA, 3, NA, NA), b=c(4, 5, NA, 6, NA, 7))
          
             a  b
          1  1  4
          2  2  5
          3 NA NA
          4  3  6
          5 NA NA
          6 NA  7
          
          x1<-t(sapply(1:nrow(x),function(y) ifelse(is.na(x[y,]),x[y-1,],x[y,])))
          
               [,1] [,2]
          [1,] 1    4   
          [2,] 2    5   
          [3,] 2    5   
          [4,] 3    6   
          [5,] 3    6   
          [6,] NA   7 
          

          要放回列名,只需使用 colnames(x1)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-03-13
            • 1970-01-01
            • 2014-05-19
            • 1970-01-01
            • 1970-01-01
            • 2014-08-12
            • 1970-01-01
            相关资源
            最近更新 更多