中位数()的奇怪行为?

时间:2011-05-05 18:02:10

标签: r

median()函数应用于数据帧时,我注意到一些不一致的行为。 “行为不一致”通常意味着我不理解某些事情,所以我希望有人愿意为我解决这个问题。

我意识到某些函数(例如min()max())会将数据框转换为向量,并在mean()sd()时返回整个df的相应值为每列返回一个值。虽然有点令人困惑,但这些行为上的差异不会引起很多问题,因为如果返回标量而不是向量,大多数代码都会中断。但是,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众神选择以一种至少在表面上似乎不一致的方式实现这些核心统计功能。我怀疑我,可能还有其他新手,可能不理解一些基本概念,我很感激你的见解。

3 个答案:

答案 0 :(得分:12)

最近在R-devel的median and data frames主题中讨论了这种确切的现象。协商一致意见似乎应该弃用mean.data.frame方法,用户应该依赖sapply

答案 1 :(得分: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 

答案 2 :(得分: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功能,但不适用于数据帧。