Замена среднего из псих :: описать для режима в фрейме данных
Мне нравится сводная статистика псих:: описать, но я хочу заменить среднее значение режимом, но только для факторных переменных. Как мне запрограммировать вывод Mode для замены setosa (или любой другой факторной переменной)? Я использую радужную оболочку для репликации, даже если она имеет только одну.
getMode <- function(df) {
ux <- na.omit(unique(df))
ux[which.max(tabulate(match(df, ux)))]
}
Mode <- apply(iris%>% select(where(is.factor)), 2, getMode)
#I only want 5 of psych's descriptive stats plus the mode.
table <- cbind(psych::describe(iris),
Mode) [,c(3,4,8,9,2, 14)]
table
Как я могу объединить среднее значение и режим в зависимости от структуры переменной?
- есть ли способ объединить
if_else
где сказать R, что делать, когдаFALSE
? Если бы я мог получить среднее значение для вывода, когда переменная не является фактором, я бы получил столбец, который объединяет средства и режимы.
Psych
создает фрейм данных, в котором имена идентифицирующих переменных нельзя выбрать, поэтому ручное кодирование или перечисление переменных в mutate() невозможно. Они также являются большинством переменных в моем наборе данных (поэтому вручную или изменить (case_when) было бы ДЕЙСТВИТЕЛЬНО утомительно, даже если бы это можно было сделать).
PS. Я пытался изменить свойapply()
к map
функции, но вывод несовместим с cbind()
потому что он перечислит другие уровни для каждого фактора. Если у вас есть лучшее представление об этой части кода или вы думаете, что здесь я мог бы объединитьgetMode
а также mean()
Я не против предложений.
1 ответ
Если вы хотите использовать другую функцию для получения такого же вывода, вы можете использовать dplyr
а также tidyr
для этого. Используя этот подход, вы можете делать то, что хотите, сifelse()
для идентификации числовых или нечисловых переменных. Единственное, что следует отметить, это то, что если у вас есть функция, вырабатывающая нечисловые значения для факторов, вывод для числовых переменных также должен быть символом. Вот почему я завернулmean()
функционировать в sprintf()
.
getMode <- function(df) {
ux <- na.omit(unique(df))
ux[which.max(tabulate(match(df, ux)))]
}
library(tidyr)
iris %>%
summarise_all(.funs = list(
mean = function(x)ifelse(is.numeric(x), sprintf("%.3f", mean(x)), as.character(getMode(x))),
sd = function(x)ifelse(is.numeric(x), sd(x), sd(as.numeric(x))),
min = function(x)ifelse(is.numeric(x), sprintf("%.3f", min(x)), levels(x)[1]),
max = function(x)ifelse(is.numeric(x), sprintf("%.3f", max(x)), levels(x)[length(levels(x))]),
n = function(x)sum(!is.na(x))
)) %>%
pivot_longer(everything(),
names_to = c("set", ".value"),
names_pattern = "(.+)_(.+)")
# A tibble: 5 x 6
# set mean sd min max n
# <chr> <chr> <dbl> <chr> <chr> <int>
# 1 Sepal.Length 5.843 0.828 4.300 7.900 150
# 2 Sepal.Width 3.057 0.436 2.000 4.400 150
# 3 Petal.Length 3.758 1.77 1.000 6.900 150
# 4 Petal.Width 1.199 0.762 0.100 2.500 150
# 5 Species setosa 0.819 setosa virginica 150
#
This also allows you to make other changes as well - for instance above, I replaced the minimum with the first level of `Species` and the maximum with the last level of `Species`. Not that this is necessarily what you'd want to do, but it's easy to change the values of the output based on the type of variable.