R语言使用for循环与if语句按行规则替换矩阵NA值的问题
R语言矩阵双类型NA值替换问题
场景规则
矩阵行对应3个不同观测个体,列对应个体的时序测量值,矩阵中NA分为两类,替换规则如下:
- 若某
NA所在位置的同行后续元素全部为NA,代表个体死亡,替换为99 - 若某
NA所在位置的同行后续存在非NA值,代表测量值缺失,替换为100 - 非
NA的原始测量值直接保留
原始输入矩阵
mat.data <- c(1, NA, NA, NA, 1, NA, 1, 2, 3) mat <- matrix(mat.data,nrow=3,ncol=3,byrow=TRUE) mat
运行输出:
[,1] [,2] [,3] [1,] 1 NA NA [2,] NA 1 NA [3,] 1 2 3
目标输出矩阵
mat1.data <- c(1, 99, 99, 100, 1, 99, 1, 2, 3) mat1 <- matrix(mat1.data,nrow=3,ncol=3,byrow=TRUE) mat1
运行输出:
[,1] [,2] [,3] [1,] 1 99 99 [2,] 100 1 99 [3,] 1 2 3
原有代码错误说明
初始代码的判断逻辑存在两处核心错误:
- 结果矩阵初始化错误:
mat1 <- matrix()未指定行列维度,赋值时会出现维度不匹配问题 - 条件判断逻辑错误:
- 索引范围
y+c(0:(ncol(mat)-y))包含了当前位置本身,当前位置值就是NA,判断永远不成立 &&运算符仅对逻辑向量的第一个元素做判断,无法识别「后续存在至少一个非NA值」的逻辑,需要搭配any()函数实现存在性判断
- 索引范围
修正后的可运行代码
# 初始化和原矩阵维度一致的结果矩阵 mat1 <- matrix(nrow = nrow(mat), ncol = ncol(mat)) for (x in 1:nrow(mat)) { for (y in 1:ncol(mat)) { # 非NA值直接保留原始测量结果 if (!is.na(mat[x, y])) { mat1[x, y] <- mat[x, y] } else { # 提取当前位置之后的所有同行元素,处理最后一列的边界情况 later_cols <- if (y == ncol(mat)) integer(0) else (y + 1):ncol(mat) later_vals <- mat[x, later_cols] # 后续存在非NA值判定为缺失值替换100,否则判定为死亡替换99 if (length(later_vals) > 0 && any(!is.na(later_vals))) { mat1[x, y] <- 100 } else { mat1[x, y] <- 99 } } } }
代码运行后得到的mat1和目标结果完全一致,其中额外处理了最后一列的边界情况,避免索引越界报错。
内容的提问来源于stack exchange,提问作者ikeagoddess
相关产品推荐
相关产品推荐

