【问题标题】:Shifting leading NA cells to the left, but NOT internal NAs in R将前导 NA 单元向左移动,但不是 R 中的内部 NA
【发布时间】:2021-02-06 17:47:39
【问题描述】:

作为前言,我注意到至少有 5 个类似问题的答案,“我如何将非 NA 单元格向左移动。”这有很多很好的答案,zoo 包有一个 na.locf() 做得很好。

我的特殊问题是我想将单元格移到最后一个前导 NA 的右侧,向左移动,替换所有前导 NA。这意味着我需要保留“内部”和尾随 NA。这是一个带有矩阵的小例子,但我的真实数据是一个大的data.frame:

matrixtest[1, 1:3] <- NA
matrixtest[3, 1:2] <- NA
matrixtest[2, 3] <- NA
matrixtest[4, 2] <- NA
matrixtest

matrixresult <-matrix(4, ncol = 4, nrow = 4)
matrixresult[1, 2:4] <- NA
matrixresult[3, 3:4] <- NA
matrixresult[2, 3] <- NA
matrixresult[4, 2] <- NA
matrixresult

操作后,matrixtest 原版应该看起来像 matrixresult 像这样:

     [,1] [,2] [,3] [,4]
[1,]   NA   NA   NA    4
[2,]    4    4   NA    4
[3,]   NA   NA    4    4
[4,]    4   NA    4    4
> matrixresult
     [,1] [,2] [,3] [,4]
[1,]    4   NA   NA   NA
[2,]    4    4   NA    4
[3,]    4    4   NA   NA
[4,]    4   NA    4    4

如果我已经错过了适用的答案,我们深表歉意。我在这个看似简单的问题上花了太多时间。

【问题讨论】:

  • 您能否详细说明一下您的示例是如何工作的?
  • Col 1:4 代表一年的几个季度。我试图将每个人的测量与他们的第一、第二、第三等时间对齐,而不是按日历对齐。 matrixtest &lt;- matrix(4, ncol = 4, nrow = 4) matrixtest[1, 1:3] &lt;- NA matrixtest[3, 1:2] &lt;- NA matrixtest[2, 3] &lt;- NA matrixtest[4, 2] &lt;- NA matrixtest matrixresult &lt;-matrix(4, ncol = 4, nrow = 4) matrixresult[1, 2:4] &lt;- NA matrixresult[3, 3:4] &lt;- NA matrixresult[2, 3] &lt;- NA matrixresult[4, 2] &lt;- NA matrixresult zoomat &lt;- zoo(matrixtest) zoomat &lt;- na.locf(zoomat, fromLast = T)
  • 对不起,我不太了解这个降价。但是,如果您使用适当的换行符运行上面的代码以使其可读,您会得到一个与上面名为matrixtest 的矩阵不同的矩阵。我想我的解释很清楚,但如果我能提供进一步帮助,请告诉我。

标签: r dplyr na zoo


【解决方案1】:

我们根据最后一列和reverse 这些行创建索引

i1 <- is.na(matrixresult[, ncol(matrixresult)])
matrixresult[i1, ] <- t(apply(matrixresult[i1,], 1, rev))

-输出

matrixresult
#     [,1] [,2] [,3] [,4]
#[1,]   NA   NA   NA    4
#[2,]    4    4   NA    4
#[3,]   NA   NA    4    4
#[4,]    4   NA    4    4

【讨论】:

    【解决方案2】:

    1) shiftLeft 使用na.trim 给出y 从其输入x 的末端移除NA,然后用它覆盖NA 向量的开头。 apply 到每一行并转置它,因为apply 导致我们想要的转置。

    library(zoo)
    
    shiftLeft <- function(x, y = na.trim(x)) replace(NA * x, seq_along(y), y)
    m <- t(apply(matrixtest, 1, shiftLeft))
    
    # check 
    identical(m, matrixresult)
    ## [1] TRUE
    

    2) 一个稍长但只涉及基数 R 的替代方案是:

    shiftLeft2 <- function(x) {
      ix <- which.max(!is.na(x))
      replace(NA*x, seq_len(length(x) - ix + 1), x[ix:length(x)])
    }
    m2 <- t(apply(matrixtest, 1, shiftLeft2))
    

    注意

    我们使用第一个矩阵作为输入,第二个矩阵用于检查。

    matrixtest <- structure(c(NA, 4, NA, 4, NA, 4, NA, NA, NA, NA, 4, 4, 4, 4, 
    4, 4), .Dim = c(4L, 4L))
    
    matrixresult <- structure(c(4, 4, 4, 4, NA, 4, 4, NA, NA, NA, NA, 4, NA, 4, NA, 
    4), .Dim = c(4L, 4L))
    

    【讨论】:

      猜你喜欢
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      相关资源
      最近更新 更多