2013-10-15 44 views
4

希望能夠清楚地解釋我想要做什麼。爲數據集應用行式函數

我有一個矩陣

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)   

我想到了什麼樣分別計算一切都像

Subsettting第一

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的矢量。

+2

你在正確的,可能做的一切F astest方式(使用'matrix'或'data.frame')。一旦你有'手段'和'偏離',只要做'(Z [,1] - 意味着)/偏離「。這樣的操作在R中被矢量化。參見Metrics的答案。 – Michele

回答

9
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 
2

這不是一個適用的問題,因爲您希望從計算中排除每行的第一列。

這樣做是先創建輸出向量,然後替換成其爲如下的迭代方法:

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 
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) 
+0

適用於本示例,但我的大型數據集。 – Paul

+2

@Paul如果速度是一個問題,那麼你應該在問題中提到。現在,你爲什麼不把所有的答案都拿回來,並且運行一個基準,並比較不同的時間點? (你可以使用'microbenchmark') – Michele

+0

注意,這個函數有一個錯誤,並給出錯誤的結果。它缺少一個paren:它應該是'process < - function(x){(x [[「value」]] - mean(c(x [[「A」]],x [[「B」]] x [[「C」]])))/ sd(c(x [[「A」]],x [[「B」]],x [[「C」]]))}' – ricardo