5

私がやりたいことを明確に説明できることを願っています。

私はマトリックスを持っています

  Z<-matrix(sample(1:40),ncol=4)

 colnames(Z)<-c("value","A","B","C")

 I would like to apply the following formula to each row in the dataset.


  Process = value - rowmean (A,B,C)
           ------------------------------------
           row-wise Standard deviation (A,B,C)         

私はすべてを別々に計算するようなものを考えました

最初にデータをサブセット化する

   onlyABC<-Z[,1:3]

次に、rowMeans を各行に適用します

     means<-apply(onlyABC,1,rowMeans)

同様に、標準偏差を個別に計算します

    deviate<-apply(onlyABC,1,SD)

そして、マトリックス「z」の値列を「平均」から減算し、「偏差」で割る方法がわかりません。

これを行うためのより簡単なアプローチはありますか?

例として、式を最初の行に適用すると、次のようになります。

 row1  32-(19+35+4/3)
       --------------
        SD(19+35+4)

同様に式を他の行にも適用し、最終的にサイズ 10 のベクトルを取得します。

4

3 に答える 3

10
ksd<-apply(Z[,-1],1,sd)
kmean<-rowMeans(Z[,-1])
 Z[,1]<-(Z[,1]-kmean)/ksd
> Z
            value  A  B  C
 [1,]  0.88181533 26  4 31
 [2,] -0.04364358 17 22  7
 [3,]  2.21200505 25 13 18
 [4,]  0.50951017  8 34 40
 [5,]  0.03866223 12  6 23
 [6,] -0.64018440 29 16 30
 [7,] -0.40927275 39 35  9
 [8,] -0.65103077 24  5  1
 [9,]  0.89658092 37 27  3
[10,]  0.26360896 11 10 28
于 2013-10-15T19:20:44.640 に答える
3

各行の最初の列を計算から除外する必要があるため、これはまったく適用の問題ではありません。

これを行う反復的な方法は、最初に出力ベクトルを作成し、次に次のように代入することです。

tranZ <- vector('numeric', length = nrow(Z))
for (i in 1:nrow(Z)) {
    tranZ[i] <- (Z[i,1] - mean(Z[i,-1])) / sd(Z[i,-1])
}

大規模なデータセットがある場合は、ベクトル化の力を使用することをお勧めします。次のことを試してください。

(Z[,1] - rowMeans(Z[,-1])) / apply(Z[, -1], 1, sd)

またはvapply

tranZ_v <- vapply(1:nrow(Z), function(X) (Z[X, 1] - mean(Z[X, -1])) / sd(Z[X, -1]),
                FUN.VALUE = numeric(1))

*applyこの場合にファミリを使用する鍵は、アプリケーションを制御することです。これを行うに1:nrow(Z)は、オブジェクト自体ではなく、関数内でオブジェクトを呼び出します。


ベンチマーク

require(rbenchmark)

process <- function(x) {
    (x[["value"]] - mean(c(x[["A"]], x[["B"]], x[["C"]]))) / sd(c(x[["A"]], x[["B"]], x[["C"]]))
}          

p2 <- function(x) {
    (x[1] - mean(x[-1])) / sd(x[-1])
}

apply_fun <- function() apply(Z, 1, process)
apply_fun2 <- function() apply(Z, 1, p2)

apply_sd <- function() (Z[,1] - rowMeans(Z[,-1])) / apply(Z[, -1], 1, sd)

vapply_anon <- function() vapply(1:nrow(Z), FUN = function(X) (Z[X, 1] - mean(Z[X, -1])) / sd(Z[X, -1]),
                FUN.VALUE = numeric(1))


bb <- benchmark(apply_fun(), apply_fun2(), apply_sd(), vapply_anon(), 
          columns = c('test', 'elapsed', 'relative'), 
          replications = 100, 
          order = 'elapsed')

適用のみを使用するベクトル化されたアプローチsdが最速です。

> bb
           test elapsed relative
3    apply_sd()   0.021    1.000
4 vapply_anon()   0.030    1.429
1   apply_fun()   0.033    1.571
2  apply_fun2()   0.034    1.619
于 2013-10-15T19:08:48.960 に答える
2
process <- function(x) {
    (x[["value"]] - mean(c(x[["A"]], x[["B"]], x[["C"]])) / sd(c(x[["A"]], x[["B"]], x[["C"]])))
}           

apply(Z, 1, process)
于 2013-10-15T19:13:03.527 に答える