让统计学家满意:Stata vs. R Student的t检验

时间:2018-07-27 10:48:11

标签: r statistics stata data-science

第1章:按性别划分的平均年龄

我与流行病学家和统计学家合作很多,他们对他们的统计输出有非常特定的要求,而且我经常无法在R中复制相同的东西(我们在Stata的流行病学家的著作)。

让我们从一个简单的例子开始,即学生t检验。我们感兴趣的是初诊时平均年龄的差异和置信区间。

1)在R中创建一些示例数据

set.seed(41)

cohort <- data.frame(
          id = seq(1,100),
          gender = sample(c(rep(1,33), rep(2,67)),100),
          age    = sample(seq(0,50),100, replace=TRUE)
          )

# save to import into Stata
# write.csv(cohort, "cohort.csv", row.names = FALSE)

b)导入数据并在Stata中运行t检验

import delimited "cohort.csv"
ttest age, by(gender)

enter image description here

我们想要的是均值的绝对差= 3.67年,合并的置信区间= 95%CI:24.59-30.57

b)在R中运行t检验

t.test(age~gender, data=cohort)

enter image description here

t.test(cohort$age[cohort$gender == 1])

enter image description here

t.test(cohort$age[cohort$gender == 2])

enter image description here

t.test(cohort$age)

enter image description here

肯定必须有另一种方法,而不是在R中运行4个t检验!

3 个答案:

答案 0 :(得分:1)

您可以尝试将所有内容放在一个函数和一些tidyverse魔术中。当然,您可以根据需要编辑输出。 boom的{​​{1}}将用于提供良好的输出。

tidy

我建议从头开始使用

foo <- function(df, x, y){
  require(tidyverse)
  require(broom)
  a1 <- df %>% 
    select(ep=!!x, gr=!!y) %>% 
    mutate(gr=as.character(gr)) %>% 
    bind_rows(mutate(., gr="ALL")) %>% 
    split(.$gr) %>% 
    map(~tidy(t.test(.$ep))) %>% 
    bind_rows(.,.id = "gr") %>% 
    mutate_if(is.factor, as.character)
  tidy(t.test(as.formula(paste(x," ~ ",y)), data=df)) %>% 
    mutate_if(is.factor, as.character) %>% 
    mutate(gr="vs") %>% 
    select(gr, estimate, statistic, p.value,parameter, conf.low, conf.high, method, alternative) %>% 
    bind_rows(a1, .)}


foo(cohort, "age", "gender")
   gr  estimate statistic      p.value parameter  conf.low conf.high                  method alternative
1   1 25.121212  9.545737 6.982763e-11  32.00000  19.76068 30.481745       One Sample t-test   two.sided
2   2 28.791045 15.699854 5.700541e-24  66.00000  25.12966 32.452428       One Sample t-test   two.sided
3 ALL 27.580000 18.301678 1.543834e-33  99.00000  24.58985 30.570147       One Sample t-test   two.sided
4  vs -3.669833 -1.144108 2.568817e-01  63.37702 -10.07895  2.739284 Welch Two Sample t-test   two.sided

答案 1 :(得分:1)

您可以创建自己的功能:

tlimits <- function(data, group){
  error <- qt(0.975, df = length(data)-1)*sd(data)/(sqrt(length(data)))
  mean <- mean(data)
  means <- tapply(data, group, mean)
  c(abs(means[1] - means[2]), mean - error, mean + error)
}

tlimits(cohort$age, cohort$gender)
        1                     
 3.669833 24.589853 30.570147 

答案 2 :(得分:1)

  

我们想要的是均值的绝对差= 3.67年,合并的置信区间= 95%CI:24.59-30.57

请注意,R的t.test进行了t检验,而您想要一个均值差和“组合置信区间”(均值在CI附近,忽略了分组变量)。因此,您不需要进行t检验,而是其他。

您可以使用以下方法获得均值差:

diff(with(cohort, tapply(age, gender, mean)))
# 3.669833 
# no point in using something more complicated e.g., t-test or lm

...和CI使用,例如:

confint(lm(age~1, data=cohort))
#                2.5 %   97.5 %
# (Intercept) 24.58985 30.57015

显然,如果经常需要,您可以轻松地将两个步骤组合为一个功能。

doit <- function(a,b) c(diff= diff(tapply(a,b,mean)), CI=confint(lm(a~1)))
with(cohort, doit(age,gender))
#   diff.2       CI1       CI2 
# 3.669833 24.589853 30.570147