【问题标题】:r: Fill two dataframe columns with the t-statistic and p-value from t.testr:用来自 t.test 的 t 统计量和 p 值填充两个数据框列
【发布时间】:2017-12-07 20:12:57
【问题描述】:

鉴于来自Lock5Data 的美国社区调查数据集,我想计算每个种族组合的收入的 t-stat(及其 Bonferroni 校正的 p 值)。我想将结果存储在包含“race1”、“race2”、“tstat”和“pval”列的数据框中。这样我可以对数据框进行排序以显示最大(或最显着)的收入差异。

library(Lock5Data)
data("ACS")
ACS$Sex <- factor(ACS$Sex, labels = c("Female","Male"))
sub_acs <- subset(ACS, select = c("Income","Sex","Race"))
sub_acs <- na.omit(sub_acs)

# form results df (t_df)
race_unique <- unique(sub_acs$Race)
t_df <- expand.grid(race1 = race_unique, race2 = race_unique)
t_df <- t_df[t_df$race1 != t_df$race2,]
rownames(t_df) <- NULL

# fill df col with t-stat
t_df$tstat <- t.test(sub_acs[sub_acs$Race == t_df$race1,]$Income, 
           sub_acs[sub_acs$Race == t_df$race2,]$Income, 
           p.adjust.methods='bonferroni')$statistic

# fill df col with p_val
t_df$pval <- t.test(sub_acs[sub_acs$Race == t_df$race1,]$Income, 
           sub_acs[sub_acs$Race == t_df$race2,]$Income, 
           p.adjust.methods='bonferroni')$p.value

不幸的是,结果 df t_df 似乎只显示了在所有行中重复的每个测试的第一个结果。如何正确映射 t 统计量和 p 值结果?欢迎提供使我当前的解决方案更加优雅和便携的答案!

【问题讨论】:

    标签: r


    【解决方案1】:

    考虑Map(mapply 的简化包装)并使用 t_df 作为辅助数据框,将唯一值传递到 m 多个 apply 方法。

    t_df <- subset(expand.grid(race1 = race_unique, race2 = race_unique), race1 < race2)
    
    ttest_proc <- function(r1, r2) {    
       output <- t.test(sub_acs[sub_acs$Race == r1,]$Income, 
                        sub_acs[sub_acs$Race == r2,]$Income, 
                        p.adjust.methods='bonferroni')
    
       df <- data.frame(race1 = r1,
                        race2 = r2, 
                        t_stat = output$statistic, 
                        p_val = output$p.value)    
       return(df)    
    }
    
    df_list <- Map(ttest_proc, t_df$race1, t_df$race2)
    
    final_df <- do.call(rbind, df_list)
    

    【讨论】:

    • 运行您的代码时,我遇到了问题。你不应该在调用expand.grid 时使用stringsAsFactors = FALSE 吗?
    • 当然,但这也取决于 acs 数据集的实际数据类型。
    【解决方案2】:

    你在寻找这样的东西吗?

    cbn <- t(combn(as.character(race_unique), 2))
    pval <- numeric(nrow(cbn))
    tstat <- numeric(nrow(cbn))
    
    for(i in seq_len(nrow(cbn))){
        a <- subset(sub_acs, Race %in% cbn[i, ])
        tt <- t.test(Income ~ Race, data = a, p.adjust.methods = 'bonferroni')
        pval[i] <- tt$p.value
        tstat[i] <- tt$statistic
    }
    
    result <- data.frame(race1 = cbn[, 1], race2 = cbn[, 2], p.value = pval, statistic = tstat)
    result 
    #  race1 race2     p.value  statistic
    #1 white black 0.190337465 -1.3173942
    #2 white other 0.007776557 -2.7231317
    #3 white asian 0.203332407  1.2831045
    #4 black other 0.365064209  0.9092968
    #5 black asian 0.050391428  1.9782605
    #6 other asian 0.005943459  2.8158303
    

    【讨论】:

    • 这可以满足我的要求并回答问题,但是我在矢量化方法中做错了什么?我不介意迭代方法,因为数据框非常小,但我想要一些大规模的性能。
    • 目前,您只分配 tstat 和 pval 列 once 而不是通过所有 组合迭代种族1 和种族2。 T 检验不能在一次调用中进行矢量化,因为您希望每次通过都会得到不同的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 2021-05-14
    • 1970-01-01
    • 2013-10-12
    • 2021-06-26
    • 2022-01-13
    相关资源
    最近更新 更多