Использование t.test внутри dplyr суммировать после группировки - PullRequest
0 голосов
/ 01 октября 2018
library(dplyr)
library(ggplot2)
library(magrittr)

diamonds %>% 
  group_by(cut) %>% 
  summarise(price_avg = t.test(
    . %>% filter(color == "E") %$% price,
    . %>% filter(color == "I") %$% price )$p.value)

Я пытаюсь получить результат t.test для применения по группам.В этом примере выясняется, есть ли значительная разница в цене на цвет при взгляде на один и тот же срез.Результат, который я получаю:

Error in summarise_impl(.data, dots) : 
Evaluation error: is.atomic(x) is not TRUE.

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Там должен быть лучшим способом сделать это.Я бы, вероятно, согласился с подходом Антониоса, но у меня возникает соблазн не использовать filter, а вместо этого распределить цены на разные цвета в столбцы списка.К сожалению, лучший код, который я мог придумать, был еще длиннее:

diamonds %>%
    group_by(cut, color) %>%
    summarize(price = list(price)) %>%
    spread(color, price) %>%
    nest() %>%
    mutate(price_avg = map_dbl(data, ~ t.test(.x$E[[1L]], .x$I[[1L]])$p.value))

Идея в том, чтобы получить два столбца списка, I и E, по цене бриллиантовсоответствующий цвет.Теперь мы можем запустить t-тест для этих двух столбцов (но, к сожалению, нам нужно отменить их список для того, чтобы это работало).

Я в основном ставлю это здесь как начало разговора.Ясно, что это не тот код, который вы когда-либо хотели бы написать, но я считаю, что должен быть короткий, логичный способ выражения этой логики (или это уже возможно, и я упускаю это из виду, или API-интерфейс данных должен бытьдополнено).

В качестве альтернативы мы можем использовать API формул для t.test:

diamonds %>%
    filter(color %in% c('E', 'I')) %>%
    nest(-cut) %>%
    mutate(price_avg = map_dbl(data, ~ t.test(price ~ color, .x)$p.value))

Для полноты, здесь то же самое, используя broom::tidy (это возвращает больше столбцов, чем просто p-значение):

diamonds %>%
    filter(color %in% c('E', 'I')) %>%
    nest(-cut) %>%
    mutate(test = map(data, ~ tidy(t.test(price ~ color, .x)))) %>%
    unnest(test)

В результате получается следующая таблица:

  cut       data             estimate estimate1 estimate2 statistic  p.value parameter conf.low conf.high method                  alternative
  <ord>     <list>              <dbl>     <dbl>     <dbl>     <dbl>    <dbl>     <dbl>    <dbl>     <dbl> <fct>                   <fct>
1 Fair      <tibble [1 × 7]>   -1003.     3682.     4685.     -2.91 3.90e- 3      327.   -1682.     -324. Welch Two Sample t-test two.sided
2 Good      <tibble [1 × 7]>   -1655.     3424.     5079.     -7.19 1.46e-12      827.   -2107.    -1203. Welch Two Sample t-test two.sided
3 Very Good <tibble [1 × 7]>   -2041.     3215.     5256.    -13.4  2.44e-39     1860.   -2339.    -1743. Welch Two Sample t-test two.sided
4 Premium   <tibble [1 × 7]>   -2407.     3539.     5946.    -15.5  7.27e-52     2405.   -2711.    -2103. Welch Two Sample t-test two.sided
5 Ideal     <tibble [1 × 7]>   -1854.     2598.     4452.    -17.0  7.63e-62     3081.   -2069.    -1640. Welch Two Sample t-test two.sided
0 голосов
/ 01 октября 2018
library(tidyverse)
library(magrittr)

diamonds %>% 
  group_by(cut) %>% 
  summarise(price_avg = t.test(price[color=="E"], price[color=="I"])$p.value)

# # A tibble: 5 x 2
#   cut       price_avg
#   <ord>         <dbl>
# 1 Fair       3.90e- 3
# 2 Good       1.46e-12
# 3 Very Good  2.44e-39
# 4 Premium    7.27e-52
# 5 Ideal      7.63e-62

Проблема в вашем решении заключается в том, что . не получит подмножество вашего набора данных (на основе вашей группировки), но весь набор данных.Проверьте это следующим образом:

diamonds %>% 
  group_by(cut) %>% 
  summarise(d = list(.))

# # A tibble: 5 x 2
#     cut       d                     
#     <ord>     <list>                
#   1 Fair      <tibble [53,940 x 10]>
#   2 Good      <tibble [53,940 x 10]>
#   3 Very Good <tibble [53,940 x 10]>
#   4 Premium   <tibble [53,940 x 10]>
#   5 Ideal     <tibble [53,940 x 10]>

Альтернативное решение будет следующим:

diamonds %>% 
  nest(-cut) %>%
  mutate(price_avg = map_dbl(data, ~t.test(
                                      .x %>% filter(color == "E") %$% price,
                                      .x %>% filter(color == "I") %$% price )$p.value))

# # A tibble: 5 x 3
#   cut       data                  price_avg
#   <ord>     <list>                    <dbl>
# 1 Ideal     <tibble [21,551 x 9]>  7.63e-62
# 2 Premium   <tibble [13,791 x 9]>  7.27e-52
# 3 Good      <tibble [4,906 x 9]>   1.46e-12
# 4 Very Good <tibble [12,082 x 9]>  2.44e-39
# 5 Fair      <tibble [1,610 x 9]>   3.90e- 3

Это работает с filter, поскольку вы можете передать filter соответствующее подмножествоваши данные (то есть столбец data) каждый раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...