Ответ 1
Это точное явление недавно обсуждалось в потоке медианы и данных на R-devel. Консенсус, похоже, заключался в том, что метод mean.data.frame
должен быть устаревшим, и пользователи должны полагаться на sapply
.
Я замечаю некоторое противоречивое поведение при применении функции median()
к dataframes. "Непоследовательное поведение" обычно означает, что я что-то не понимаю, поэтому, надеюсь, кто-то захочет прояснить это для меня.
Я понимаю, что некоторые функции (например, min()
, max()
) преобразуют данные в вектор и возвращают соответствующее значение для всего df, а mean()
и 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 NA
, а median(dat4)
возвращает [1] 50.5 149.5
! Я бы ожидал, что обе или ни одна из них не сработает. Итак, я явно не понимаю, как работает функция median()
.
Кроме того, функции, такие как sd
, mean()
, min()
и max()
, дают ожидаемые (если кажутся непоследовательными) результаты во всех вышеперечисленных случаях.
Я знаю, что я могу использовать что-то вроде sapply(dat2, median)
, чтобы получить нужный результат, но мне интересно, почему боги R решили реализовать эти основные функции статистики таким образом, чтобы, по крайней мере, на поверхности, казалось непоследовательным. Я подозреваю, что я и, возможно, другие неофиты, вероятно, не понимают фундаментальную концепцию, и я был бы признателен вам за понимание.
Это точное явление недавно обсуждалось в потоке медианы и данных на R-devel. Консенсус, похоже, заключался в том, что метод mean.data.frame
должен быть устаревшим, и пользователи должны полагаться на sapply
.
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
Самый простой способ - это пакет 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
, но не для фреймов данных.