Возьмите среднее значение при игнорировании определенного набора значений в цепочке dplyr - PullRequest
3 голосов
/ 11 июля 2019

Допустим, у меня есть следующие данные:

values = data.frame(score = c(1, 2, 3, 4, 5, 999, 2, 3, 999, 4),
                    score_2 = c(1, 4, 8 , 4, 999, 2, 3, 2, 1, 0))
values %>% 
  summarize(mean_score = mean(score),
            mean_score_2 = mean(score_2))

Я хочу вычислить среднее значение для каждого из столбцов в наборе данных, игнорируя при этом значение «999».

Так что я могу сделать что-то вроде этого:

values %>% 
  filter_all(all_vars(!grepl('999',.))) %>%
  summarize(mean_score = mean(score),
            mean_score_2 = mean(score_2))

Но это удалит строки 6, 9 и 5 как из Score, так и Score_2 (потому что это местоположение 999). Как выборочно вычислить средние значения, игнорируя определенные значения, не удаляя целые строки?

Для score результирующий вывод должен быть 3, для score_2 результирующий вывод должен быть 2.78

Ответы [ 2 ]

5 голосов
/ 11 июля 2019

Мы можем использовать summarise_all или summarise_if (только для выбора numeric столбцов) и выбирать значения столбцов с помощью оператора сравнения (!=).

library(dplyr)
values %>%
     summarise_all(~ mean(.[.!= 999]))

Если имеется несколько значений, используйте %in% и отрицайте !

values %>%
     summarise_all(~ mean(.[! . %in% c(999, 994)]))
2 голосов
/ 11 июля 2019

Вы также можете учитывать это:

values %>% 
    gather(key = "score_type", value = "val") %>% 
    filter(val != 999) %>% 
    group_by(score_type) %>% 
    summarise(mean_score = mean(val)) %>% 
    ungroup()

Результаты

# A tibble: 2 x 2
  score_type mean_score
  <chr>           <dbl>
1 score            3   
2 score_2          2.78

Примечания

ИМХО решение дает вам следующие преимущества:

  • Приближает вас к Tidy Data [PDF] идея обработки данных в dplyr.Если вы намереваетесь получить сводную статистику по типу оценки, это предпочтительный формат данных.

  • Вы можете легко расширить фильтр в удобочитаемой форме.Если вы хотите использовать нотацию ~, вы в конечном итоге сделаете что-то подобное для дополнительных операций:

    values %>%
        summarise_all(list( ~ mean(.[!. %in% c(999, 994)]), 
                            ~ max(.[!. %in% c(999, 994)])))
    

    Это нецелесообразно, так как для более сложного фильтра вы получитенечитаемые высказывания или вектор, который вам придется создавать и приводить только по этой причине.Кроме того, результаты не отформатированы

    #   score_mean score_2_mean score_max score_2_max
    # 1          3     2.777778         5           8
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...