Замена среднего из псих :: описать для режима в фрейме данных

Мне нравится сводная статистика псих:: описать, но я хочу заменить среднее значение режимом, но только для факторных переменных. Как мне запрограммировать вывод 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

Как я могу объединить среднее значение и режим в зависимости от структуры переменной?

  1. есть ли способ объединить 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. 
Другие вопросы по тегам