根据组/类别执行多个配对t检验

Use*_*009 5 r t-test

我坚持在Rstudio中为多个类别执行t.tests.我希望得到每种产品类型的t.test的结果,比较在线和离线价格.我有800多种产品类型,因此不希望为每个产品组手动执行此操作.

我有一个数据帧(超过200万行)命名数据,如下所示:

> Product_type   Price_Online   Price_Offline   
1   A            48             37
2   B            29             22
3   B            32             40
4   A            38             36
5   C            32             27
6   C            31             35
7   C            28             24
8   A            47             42
9   C            40             36
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望R将t.test的结果写入另一个名为product_types的数据框:

    > Product_type   
    1   A           
    2   B            
    3   C          
    4   D          
    5   E         
    6   F            
    7   G            
    8   H            
    9   I            
   800 ...
Run Code Online (Sandbox Code Playgroud)

变为:

> Product_type   t         df       p-value   interval    mean of difference            
    1   A           
    2   B            
    3   C          
    4   D          
    5   E         
    6   F            
    7   G            
    8   H            
    9   I            
   800 ...
Run Code Online (Sandbox Code Playgroud)

如果我在不同的数据框架中拥有所有产品类型,那么这就是公式:

t.test(Product_A$Price_Online, Product_A$Price_Offline, mu=0, alt="two.sided", paired = TRUE, conf.level = 0.99)
Run Code Online (Sandbox Code Playgroud)

必须有一种更简单的方法来做到这一点.否则,我需要制作800多个数据帧,然后执行800次t测试.

我尝试使用列表和lapply,但到目前为止它不起作用.我还尝试了多列的t-Test:https: //sebastiansauer.github.io/multiple-t-tests-with-dplyr/

然而,最后他仍然手动插入男性和女性(对我来说超过800个类别).

yee*_*dle 17

这样做的整洁方式是使用dplyr和扫帚:

library(dplyr)
library(broom)

df <- data %>% 
  group_by(Product_type) %>% 
  do(tidy(t.test(.$Price_Online, 
                 .$Price_Offline, 
                 mu = 0, 
                 alt = "two.sided", 
                 paired = TRUE, 
                 conf.level = 0.99))))
Run Code Online (Sandbox Code Playgroud)

比我的基础解决方案更具可读性,它为您处理列名称!

编辑 更实用的方法而不是使用do(参见r4ds)是nest为每种产品类型创建嵌套数据框,然后使用mapfrom 为每个嵌套数据框运行t检验purrr.

library(broom)
library(dplyr)
library(purrr)
library(tidyr)

t_test <- function(df, mu = 0, alt = "two.sided", paired = T, conf.level = .99) {
  tidy(t.test(df$Price_Offline, 
              df$Price_Online,
              mu = mu, 
              alt = alt,
              paired = paired,
              conf.level = conf.level))
}

d <- df %>%
  group_by(Product_type) %>%
  nest() %>%
  mutate(ttest = map(data, t_test)) %>%
  unnest(ttest, .drop = T)
Run Code Online (Sandbox Code Playgroud)


yee*_*dle 6

一种方法是使用by

result <- by(data, data$Product_type, function(x) 
  t.test(x$Price_Online, x$Price_Offline, mu=0, alt="two.sided", 
         paired=TRUE, conf.level=0.99)[c(1:9)])
Run Code Online (Sandbox Code Playgroud)

要在数据框中获取结果,您必须rbind

type.convert(as.data.frame(do.call(rbind, result)), as.is=TRUE)
#     statistic parameter   p.value             conf.int estimate null.value   stderr alternative        method
# A    2.267787         2 0.1514719  -20.25867, 32.25867        6          0 2.645751   two.sided Paired t-test
# B -0.06666667         1 0.9576214  -477.9256, 476.9256     -0.5          0      7.5   two.sided Paired t-test
# C    1.073154         3 0.3618456 -9.996192, 14.496192     2.25          0 2.096624   two.sided Paired t-test
Run Code Online (Sandbox Code Playgroud)

或者,使用管道:

do.call(rbind, result) |> as.data.frame() |> type.convert(as.is=TRUE)
Run Code Online (Sandbox Code Playgroud)

数据

data <- structure(list(Product_type = c("A", "B", "B", "A", "C", "C", 
"C", "A", "C"), Price_Online = c(48L, 29L, 32L, 38L, 32L, 31L, 
28L, 47L, 40L), Price_Offline = c(37L, 22L, 40L, 36L, 27L, 35L, 
24L, 42L, 36L)), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6", "7", "8", "9"))
Run Code Online (Sandbox Code Playgroud)