2013-03-27 145 views
6

不好意思問這個...這肯定是一個常見問題,這是一個愚蠢的問題,但它一直在困擾着我。假設我想在數據幀的每個數字列的方差,如爲什麼var在R中扮演cov的角色?

df <- data.frame(x=1:5,y=seq(1,50,10)) 

當然,我嘗試

var(df) 

而不是給我什麼,我原先希望的,這將是什麼像

x y 
2.5 250 

我得到這個

 x y 
x 2.5 25 
y 25.0 250 

其中對角線有差異,其他位置有協方差。當我查找幫助(var)並且讀取「var只是cov的另一個接口」時,這是有意義的。當然,變量是一個變量與其自身之間的協方差。輸出有點混淆,但我可以沿對角線讀取,或者只使用diag(var(df)),sapply(df, var)lapply(df, var)或通過在df$xdf$y上重複呼叫var來生成差異。

但是爲什麼?差異是一種常規的基本描述性統計,僅次於平均值。不應該將它應用於數據框的列是完全微不足道的嗎?當我只要求差異時,爲什麼要給我協方差?只是好奇。感謝您對此的任何評論。

+2

[這](http://stackoverflow.com/q/9424311/324364)問題也可能會使一些很好的閱讀。 – joran 2013-03-27 03:57:39

回答

10

的慣用方法是

sapply(df, var) 

var具有用於data.frames的方法,其涉及data.frames通過強迫到matrix

Variance是一個常規的基本描述性統計量,協方差和相關性也是如此。它們都是相互關聯和有趣的,特別是如果你打算使用線性模型。

你總是可以創建自己的函數來執行,只要你想

Var <- function(x,...){ 
    if(is.data.frame(x)) { 
    return(sapply(x, var,...))} else { return(var(x,...))} 
} 
+0

說'var'有一個數據框的方法可能有點混亂,它不在通常的R方法的意義上(S3或S4方法)。數據幀被簡單地轉換爲矩陣,然後應用'cov'。 – 2013-03-27 04:06:51

+0

@GavinSimpson - 編輯(謝謝澄清) – mnel 2013-03-27 04:08:58

+0

謝謝mnel,GavinSimpson,SimonO101。這些都是非常有用的答案,就像喬蘭的鏈接一樣 - 儘管我已經把它們全部投了,但我不願意將其標記爲答案。我知道了。 – Mars 2013-03-27 15:20:32

8

這是記錄在?var,即:

Description: 

    ‘var’, ‘cov’ and ‘cor’ compute the variance of ‘x’ and the 
    covariance or correlation of ‘x’ and ‘y’ if these are vectors. If 
    ‘x’ and ‘y’ are matrices then the covariances (or correlations) 
    between the columns of ‘x’ and the columns of ‘y’ are computed. 

其中「矩陣」一文指"matrix"類的對象和"data.frame"

var沒有傳統意義上的數據幀的方法。 var只需通過as.matrix將輸入數據幀強制轉換爲矩陣,然後在該矩陣上調用cov

爲了迴應這個問題,我想方差與協方差的概念密切相關,並保持代碼簡單R Core爲類矩陣對象的協方差編寫了單個實現,並將其用於因爲這是您想要從矩陣中選擇最可能的東西。

或者更簡潔; R核心是如何實現這一點的。學會和它一起生活。:-)

另請注意,R正在從類似meansd之類的功能轉移到數據幀的組件(列)上。如果你想申請任何這些功能,包括var,您需要調用是這樣的:

apply(foo, 2, mean) ## for matrices 
sapply(foo, mean) ## for data frames 

或更快的具體方案

colMeans(foo) 

在這種情況下,我懷疑 diag(var(df))會通過 apply函數族之一反覆調用 var來獲得差異的最有效方法。 diag(var(df))不可能比sapply(df, var)更快,因爲前者必須計算所有的協方差以及差異。

+0

+1,我編輯了我的回覆,注意缺少一個傳統的'方法' – mnel 2013-03-27 04:08:29

+0

我很好奇diag(var(df))或sapply(df,var)會更快。在本例中:'df < - data.frame(x = rnorm(4 * 10^7),y = rbinom(4 * 10^7,100,.5))'''sapply(df,var)'大約1.8秒,並且在操作期間將R的RAM使用量從大約1GB增加到1.7GB,而sapply(diag(var(df)))大約需要4.5秒,並且在操作期間將RAM從1GB增加到大約2.5GB(R 2.15.0,MacBook Air 1.6GHz Intel Core 2 Duo,4GB RAM,OS X 10.6.8)。 – Mars 2013-03-27 16:15:12

+0

@Mars不,你有錯。整個調用是'diag(var(df))';你不會'喂寶寶'。正如你在你的問題中顯示的那樣'var(df)'返回'df'的整個方差 - 協方差矩陣。你想要的位在對角線上,所以我們用'diag()'來提取它們。無論如何,我現在意識到這種方式也計算協方差,因此可能比'sapply'版本慢。 – 2013-03-27 16:29:31

1

您的實際答案已由@GavinSimpson覆蓋。對於var你也可以只使用:

sd(df)^2 
# x  y 
# 2.5 250.0 

並通過這樣做,你會看到什麼@GavinSimpson意味着大約R「從像meansd具有功能移開上的組件運行的數據幀(列)「。已過時意味着功能也許可以用R的即將到來的版本變化退役,如果你不聽從警告你的代碼可能會破裂並適當改變:

警告消息: SD()已過時。 改用sapply(*,sd)。

所以我們可以使用:

sapply(df,sd)^2 
# x  y 
# 2.5 250.0 

這讓我們完全一樣的結果。

但是,這樣做很有點愚蠢,因爲您在每列上有效地調用了(sqrt(var(x, na.rm = na.rm)))^2!相反,如@ mnel所示,sapply(df , var)是您應該如何獲得每個列向量的方差。

相關問題