4

行列の各列の NA をその列の中央値に置き換えようとしていますが、使用しようとするとlapplyエラーsapplyが発生します。for ループを使用し、一度に 1 つの列を変更すると、コードが機能します。何が間違っていますか?

例:

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)
}
4

4 に答える 4

7

matrixStatsいずれかのループを使用して列ごとの中央値を計算するのではなく、パッケージを使用してこれをベクトル化することをお勧めします (sapply各反復で関数を評価するという意味でループでもあります)。

まず、NAs インデックスを作成します。

indx <- which(is.na(mat), arr.ind = TRUE)

NA次に、事前に計算された列の中央値を使用して、インデックスに従って s を置き換えます

mat[indx] <- matrixStats::colMedians(mat, na.rm = TRUE)[indx[, 2]]
于 2016-01-18T23:39:10.227 に答える
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)もう少しパフォーマンスを求めて立ち寄ることもできます。

于 2016-01-19T00:24:43.690 に答える
0

次を使用して、結果としてへの変換data.frameと元への変換を介して、簡単にアクセスできる可能性があります。matrixvapply

vapply(as.data.frame(mat1), function(x)
   replace(x, is.na(x), median(x,na.rm=TRUE)), FUN.VALUE=numeric(nrow(mat1)) 
)
于 2016-01-18T23:28:11.930 に答える