必须有更好的方法来做到这一点。我可能会采用 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))
这里的想法是获取两个列表列,I 和 E,分别对应颜色的钻石价格。我们现在可以在这两列上运行 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