【问题标题】:Using a t.test inside dplyr summarise after grouping分组后在 dplyr 中使用 t.test 汇总
【发布时间】:2018-10-01 09:59:57
【问题描述】:
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.

【问题讨论】:

  • 谢谢,已添加

标签: r dplyr


【解决方案1】:
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,因为您每次都可以将适当的数据子集(即列data)传递给filter

【讨论】:

  • 啊,我似乎对 dplyr 有点太着迷了。无论如何要在摘要中使用 filter() 吗?#
  • @pluke 不好,不。我认为“推荐”的方法是通过tidyr::nest + purrr + broom 而不是纯 dplyr。
  • 我同意@KonradRudolph 的观点,但是您认为如何在summarise 中使用filter?为什么?
  • 如上图,我想用filter(color == "E")代替base R
  • 我不知道仅使用dplyr 的任何方法。但是,请注意,问题不在于filter 命令,而是您无法使用正确的数据子集到filter 的事实。你可以这样使用purrrdiamonds %&gt;% nest(-cut) %&gt;% mutate(price_avg = map_dbl(data, ~t.test( .x %&gt;% filter(color == "E") %$% price, .x %&gt;% filter(color == "I") %$% price )$p.value))
【解决方案2】:

必须有更好的方法来做到这一点。我可能会采用 Antonios 的方法,但我很想不使用 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))

这里的想法是获取两个列表列,IE,分别对应颜色的钻石价格。我们现在可以在这两列上运行 t 检验(但不幸的是,我们需要取消列出它们才能工作)。

我主要把它放在这里作为对话的开始。显然这不是你想写的代码,但我相信应该有一种简短的、合乎逻辑的方式来表达这个逻辑(要么这已经是可能的,我忽略了它,要么需要整洁的数据 API增强)。

或者我们可以使用t.test的公式API:

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

【讨论】:

    猜你喜欢
    • 2014-12-02
    • 2021-01-20
    • 2015-10-06
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多