2012-11-02 32 views
0

我剛剛爲所有列上的Matrix變換中的z變形寫了一個非常基本的函數。它看起來像這樣:所有列上的簡單z變換

sapply(MyObject, function(x){(x-mean(x))/sd(x)})

我隨機抽查我的函數矩陣內的一些細胞,它似乎很好地工作。不過我想確認這個功能還行,因爲我對R非常陌生,在互聯網上找不到任何好的例子。

+3

你可能想看看'規模()':-)(順便說一句,如果有遺漏值,你的函數將失敗:你需要添加'na.rm = TRUE') – chl

+0

我知道那裏已經有一個函數了:)但是它是非常糟糕的,因爲當我使用這種比例函數時:'sapply(MyObject,function(x){scale( x)})'我得到完全不同的值......可能是他正在執行整個矩陣的均值和標準差的標度轉換? – Joschi

+2

你不需要'sapply()'應用'scale()'。只要做'scale(MyObject)'。你應該得到相同的結果然後(非常相似,它們都是矩陣,但是scale()結果將具有屬性)。 –

回答

4

你應該看看scale()這是爲你做的。

您的功能接近正確;您應該將na.rm = TRUE添加到sd()mean()函數調用中。

我會寫(如果不使用scale())函數使用sweep()而不是sapply()。例如。

ztran <- function(x, na.rm = TRUE) { 
    mns <- colMeans(x, na.rm = na.rm) 
    sds <- apply(x, 2, sd, na.rm = na.rm) 
    x <- sweep(x, 2, mns, "-") 
    x <- sweep(x, 2, sds, "/") 
    x 
} 

在使用中,我們有

> df <- data.frame(matrix(1:9, ncol = 3)) 
> ztran(df) 
    X1 X2 X3 
1 -1 -1 -1 
2 0 0 0 
3 1 1 1 
> scale(df) 
    X1 X2 X3 
[1,] -1 -1 -1 
[2,] 0 0 0 
[3,] 1 1 1 
attr(,"scaled:center") 
X1 X2 X3 
2 5 8 
attr(,"scaled:scale") 
X1 X2 X3 
1 1 1 

sweep是這種操作的一個非常有用的向量化工具。還要注意,sapply()簡化爲矩陣,這可能不是你想要的。 sweep()不這樣做:

> class(ztran(df)) 
[1] "data.frame" 
> class(sapply(df, function(x){(x-mean(x))/sd(x)})) 
[1] "matrix" 
+0

好的。我得到了這個工作。但我不確定我是否理解了'sweep'的優點。掃描是否允許我執行選擇列的功能,並且sapply會自動運行整個矩陣? – Joschi

+1

不,'sweep()'適用於所有列('2')[或行(將'2'更改爲'1')]。優點是i)'sweep()'是矢量化的,'sapply()'解決方案不是,它只是隱藏循環; 'sapply()'不能很好地與數據幀一起播放,正如它被簡化爲一個矩陣所見證的那樣。這兩個選項都允許你選擇哪些列處理:'sweep(df [,c(1,3)],....)'或'sapply(df [,c(1,3)],.... )'。 –

+0

好的。現在更清楚了。謝謝你的幫助! – Joschi