微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将前导 NA 单元向左移动,但不是 R

如何解决将前导 NA 单元向左移动,但不是 R

作为前言,我注意到对于类似问题“如何向左移动非 NA 单元格”至少有 5 个答案。对此有很多很好的答案,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
     [,]    4   NA   NA   NA
[2,]    4    4   NA   NA
[4,]    4   NA    4    4

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

解决方法

我们根据最后一列创建索引并rev修改这些行

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
,

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

library(zoo)

shiftLeft <- function(x,y = na.trim(x)) replace(NA * x,seq_along(y),y)
m <- t(apply(matrixtest,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,shiftLeft2))

注意

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

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

matrixresult <- structure(c(4,4L))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。