2011-05-05 91 views
10

median()函數應用於數據框時,我注意到一些不一致的行爲。 「不一致的行爲」通常意味着我不瞭解某些東西,所以我希望有人願意爲我解決這個問題。奇怪的行爲與中位數()?

我知道一些功能(例如,min()max())轉換數據幀到載體和用於同時mean()整個DF返回對應的值和sd()對於每列返回一個值。雖然有點令人困惑,但這些行爲上的差異並不會導致很多問題,因爲如果標量返回而不是向量,大多數代碼都會中斷。但是,median()似乎不一致。例如:

dat <- data.frame(x=1:100, y=2:101) 
median(dat) 

返回向量:[1] 50.5 51.5

但是,有時它打破:

dat2 <- data.frame(x=1:100, y=rnorm(100)) 
median(dat2) 

返回:[1] NA NA Warning messages: 1: In mean.default(X[[1L]], ...) : argument is not numeric or logical: returning NA 2: In mean.default(X[[2L]], ...) : argument is not numeric or logical: returning NA

然而,median(dat2$x)median(dat2$y)都產生正確的結果。

還要考慮以下幾點:

dat3 <- data.frame(x=1:100, y=1:100) 
dat4 <- data.frame(x=1:100, y=100:199) 

在上面,median(dat3)回報[1] 50.5 NAmedian(dat4)回報[1] 50.5 149.5!我期望這兩種或兩者都不起作用。所以,我顯然不瞭解median()函數是如何工作的。

此外,像sdmean()min()max()所有功能得到在所有上述情況下,它們預期的(如果表面上矛盾的)的結果。

我知道我可以使用像sapply(dat2, median)這樣的東西來獲得必要的結果,但是我想知道爲什麼R神選擇以至少在表面上看起來不一致的方式來實現這些核心統計函數。我懷疑我和其他新手可能不瞭解某些基本概念,我很感激你的洞察力。

+1

我希望我已經更仔細地閱讀過R地獄。我剛回去看了看,作者說:「帶有數據框的中位數的例子是一個麻煩的例子......沒有數據框架的中位數方法,在這種情況下,它得到了正確的答案,但那是在其他情況下,你會得到奇怪的答案。「 (第54頁)。我現在有動力讓R煉獄在這個週末有一個很好的,堅實的閱讀。 – 2011-05-06 03:29:20

回答

12

這個確切的現象最近在R-devel的median and data frames線程中討論過。共識似乎是mean.data.frame方法應該被棄用,用戶應該依靠sapply

+1

+1強調'mean.data.frame'問題。 – aL3xa 2011-05-05 18:09:27

+2

完美,謝謝!我沒有找到那個線索,我有點尷尬。很明顯,「mean」和「sd」是不一致的函數,而不是「中位數」(儘管我仍然認爲它在其他方面不一致)。事後看來,奇怪的是期望一個函數通常聚合一個數字向量來處理數據幀。一個更好的問題會問爲什麼mean.data.frame首先實現。 – 2011-05-05 18:39:36

5

median對於data.frame類對象還沒有一個方法,不像mean。使用plyr包和colwise函數來實現所需的結果。或者使用*apply函數族。

> sapply(mtcars, median)                          
    mpg  cyl disp  hp drat  wt qsec  vs  am gear            
19.200 6.000 196.300 123.000 3.695 3.325 17.710 0.000 0.000 4.000            
    carb                              
    2.000                              
> colwise(median)(mtcars)                          
    mpg cyl disp hp drat wt qsec vs am gear carb                  
1 19.2 6 196.3 123 3.695 3.325 17.71 0 0 4 2 
+0

感謝aL3xa。我一直習慣使用補給品。我對R還是有點新意,但有時還會感到不安,因爲函數沒有指定參數類型,並且如果有不適當的東西傳遞給它們,就會拋出錯誤。聽起來最好的習慣是在需要逐列結果時始終使用sapply或colwise。 – 2011-05-05 18:56:14

+0

你可以使用'* apply'系列,這是一個好習慣。 – aL3xa 2011-05-05 20:10:25

1

最簡單的方法是用包miscTools

> library(miscTools) 
> dat3 <- data.frame(x=-50:50, y=(-50:50)^2) 
> colMedians(dat3) 
    x y 
    0 625 

這是正確的,不像

> median(dat3) 
[1] 0 850 

matrixStats也有colMedians功能,但不適合dataframes。

+0

謝謝@亨利。我不知道miscTools;看起來好像有幾個很好的線性代數工具。 – 2011-05-06 03:26:18