用该列的中位数替换矩阵每一列中的 NA
Replacing NA's in each column of matrix with the median of that column
我试图用该列的中值替换矩阵每一列中的 NA,但是当我尝试使用 lapply
或 sapply
时出现错误;当我使用 for 循环并且一次更改一列时代码有效,我做错了什么?
示例:
set.seed(1928)
mat <- matrix(rnorm(100*110), ncol = 110)
mat[sample(1:length(mat), 700, replace = FALSE)] <- NA
mat1 <- mat2 <- mat
mat1 <- lapply(mat1,
function(n) {
mat1[is.na(mat1[,n]),n] <- median(mat1[,n], na.rm = TRUE)
}
)
for (n in 1:ncol(mat2)) {
mat2[is.na(mat2[,n]),n] <- median(mat2[,n], na.rm = TRUE)
}
lapply
遍历列表。您是要遍历列吗?
matx <- sapply(seq_len(ncol(mat1)), function(n) {
mat1[is.na(mat1[,n]),n] <- median(mat1[,n], na.rm = TRUE)
})
虽然这基本上只是在做您的循环示例所做的事情(但可能更快)。
通过转换为 data.frame
并返回 matrix
,您可能会更容易到达那里,使用 vapply
:
vapply(as.data.frame(mat1), function(x)
replace(x, is.na(x), median(x,na.rm=TRUE)), FUN.VALUE=numeric(nrow(mat1))
)
我建议使用 matrixStats
包对其进行矢量化,而不是使用任一循环计算每列的中值(sapply
在某种意义上也是一个循环,它在每个循环中评估一个函数迭代)。
首先,我们将创建一个 NA
s 索引
indx <- which(is.na(mat), arr.ind = TRUE)
然后,使用预先计算的列中位数并根据索引
替换NA
s
mat[indx] <- matrixStats::colMedians(mat, na.rm = TRUE)[indx[, 2]]
您可以使用 sweep
:
sweep(mat, MARGIN = 2,
STATS = apply(mat, 2, median, na.rm=TRUE),
FUN = function(x,s) ifelse(is.na(x), s, x)
)
编辑:
您还可以加入 STATS=matrixStats::colMedians(mat, na.rm=TRUE)
以获得更好的性能。
我试图用该列的中值替换矩阵每一列中的 NA,但是当我尝试使用 lapply
或 sapply
时出现错误;当我使用 for 循环并且一次更改一列时代码有效,我做错了什么?
示例:
set.seed(1928)
mat <- matrix(rnorm(100*110), ncol = 110)
mat[sample(1:length(mat), 700, replace = FALSE)] <- NA
mat1 <- mat2 <- mat
mat1 <- lapply(mat1,
function(n) {
mat1[is.na(mat1[,n]),n] <- median(mat1[,n], na.rm = TRUE)
}
)
for (n in 1:ncol(mat2)) {
mat2[is.na(mat2[,n]),n] <- median(mat2[,n], na.rm = TRUE)
}
lapply
遍历列表。您是要遍历列吗?
matx <- sapply(seq_len(ncol(mat1)), function(n) {
mat1[is.na(mat1[,n]),n] <- median(mat1[,n], na.rm = TRUE)
})
虽然这基本上只是在做您的循环示例所做的事情(但可能更快)。
通过转换为 data.frame
并返回 matrix
,您可能会更容易到达那里,使用 vapply
:
vapply(as.data.frame(mat1), function(x)
replace(x, is.na(x), median(x,na.rm=TRUE)), FUN.VALUE=numeric(nrow(mat1))
)
我建议使用 matrixStats
包对其进行矢量化,而不是使用任一循环计算每列的中值(sapply
在某种意义上也是一个循环,它在每个循环中评估一个函数迭代)。
首先,我们将创建一个 NA
s 索引
indx <- which(is.na(mat), arr.ind = TRUE)
然后,使用预先计算的列中位数并根据索引
替换NA
s
mat[indx] <- matrixStats::colMedians(mat, na.rm = TRUE)[indx[, 2]]
您可以使用 sweep
:
sweep(mat, MARGIN = 2,
STATS = apply(mat, 2, median, na.rm=TRUE),
FUN = function(x,s) ifelse(is.na(x), s, x)
)
编辑:
您还可以加入 STATS=matrixStats::colMedians(mat, na.rm=TRUE)
以获得更好的性能。