繁体   English   中英

如何从多个组的 cor.test 结果中提取估计值和 p 值?

[英]How do I extract estimates and p-value from cor.test results across multiple groups?

我有一组数据,在多个时间点有多个组(下面的示例剪切):

在此处输入图像描述

我一直在尝试在每个状态和每个性别之间的 X 和 Y 之间进行多个 cor.test。

我很难弄清楚组比较,所以我按状态过滤并将我的性别 cor.tests 分别拆分为 Status = Red 和 Status = Blue(使用过滤器)。

这是我当前的代码,它在每个性别上运行 cor.test:

    red_status <- all %>% filter(status == "Red")
    cor_red <- by(red_status, red_status$gender, 
                  FUN = function(df) cor.test(df$X, df$Y, method = "spearman"))

output 结果显示了每个性别的 3 个不同的 cor.test:


red_status$gengrp: M
    Spearman's rank correlation rho

data:  df$X and df$Y
S = 123.45, p-value = 0.123
alternative hypothesis: true rho is not equal to 0
sample estimates:
     rho 
0.123456 

----------------------------------

red_status$gengrp: F
... (same output style as gengrp: M ^)

----------------------------------
red_status$gengrp: O
... (same output style as gengrp: M ^)

我想要做的是提取所有性别 cor.test 的估计值和 p 值,并将它们放在 dataframe 中。

我想我可以使用 data.frame() function 来提取性别名称和相关元素,然后为 p 值添加另一列,但是这样做给了我一个错误:

# Where red_status[1] is gender names (M,F,O) and red_status[[3:4]] are the Spearman p-value and rho estimate *within each gender category*
data.frame(group = dimnames(red_status)[1], est = as.vector(red_status)[[3]], 
pval = as.vector(red_status[[4]])
Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
  cannot coerce class ‘"htest"’ to a data.frame

由于我按 Status == Red 过滤,因此我必须再次重新运行代码以获得 Status == Blue 的性别 cor.test 结果,然后在最后将估计值和 p 值全部绑定到 1 df。

我的目标是能够创建一个数据框,显示每个状态性别的相关估计和 p 值:

Status   Gender   Estimate(rho)    P-value
   Red        M            1.23      0.123
   Red        F            0.45      0.054
   Red        O             ...        ...
  Blue        M           0.004      0.123
  Blue        F             ...        ...
  Blue        O             ...        ...

任何帮助/提示将不胜感激。

答案基于@Ruam Pimentel 关于 rstatix package 的评论。

使用管道 + cor_test() function,我可以按状态和性别分组来运行相关性测试。 cor_test() function 旨在 output dataframe 包含相关的所有元素(即统计、p 值、估计),所有这些都取决于选择的相关方法。

这是有效的代码:

 r <- dfall %>%
                group_by(status, gender) %>%
                cor_test(X, Y, method = "spearman")

结果(编辑了数字):

  status  gengrp var1   var2   cor  statistic    p   method  
  <chr>   <fct>  <chr>  <chr> <dbl>     <dbl>  <dbl> <chr>   
1 Red       M     X       Y    0.98    -0.123  0.123  Spearman
2 Red       F     X       Y    0.12     0.456  0.456  Spearman
3 Red       O     X       Y    0.34     0.944  0.789  Spearman
4 Blue      M     X       Y    0.56     0.246  0.101  Spearman
5 Blue      F     X       Y    0.78    0.4107  0.111  Spearman
6 Blue      O     X       Y     0.9     0.123  0.122  Spearman

虽然rstatix解决方案比 Base R 解决方案需要的代码少得多,但我发布了一个代码来证明可以在 Base R 中创建请求的 output。

Base R 解决方案的关键是了解如何从cor.test()导航 output object 以提取请求的内容,将其转换为单行数据帧,以及rbind()将对象列表转换为单个数据帧。

首先,我们生成一些数据。

set.seed(9108171) # for reproducibility
gender <- rep(c("F","M", "O"),40)
status <- c(rep("Red",60),rep("Blue",60))
x <- round(rnorm(120,mean = 6,sd = 2),1)
y <- round(rnorm(120,mean = 8,sd = 1),1)

df <- data.frame(gender,status, x, y)

接下来,我们根据原始帖子中的代码筛选出红色项目,然后运行 cor.test() function。

# filter red
library(dplyr)
red_status <- filter(df,status == "Red")
cor_red <- by(red_status, red_status$gender,
              FUN = function(df) cor.test(df$x, df$y, method = "spearman"))

最后我们使用lapply()来提取数据并将其组合成一个数据框。 请注意提取运算符[[形式的使用,它从cor.test()生成的列表列表中删除了一层嵌套。 另请注意我们如何使用名称向量、 gender类别来驱动lapply() 这些值用于区分先前调用cor.test()时的分组。

# extract the required data
theResults <- lapply(c("F","M","O"),function(x){
  aTest <- cor_red[[x]]
  data.frame(status = "Red",
             test = names(aTest$statistic),
             value = aTest$statistic,
             p_value = aTest$p.value,
             rho = aTest$estimate)
})

# rbind the results into a single data frame
do.call(rbind,theResults)

...以及红色状态的结果:

> do.call(rbind,theResults)
   status test    value   p_value         rho
S     Red    S 1072.672 0.4137465  0.19347947
S1    Red    S 1396.400 0.8344303 -0.04992459
S2    Red    S 1281.132 0.8777763  0.03674259

我们可以对 Blue 状态重复该过程并将结果结合起来以获得以下结果:

> rbind(blueResults,redResults)
    status test    value    p_value         rho
S     Blue    S 1541.034 0.50402812 -0.15867211
S1    Blue    S 1087.954 0.44253280  0.18198950
S2    Blue    S 1880.742 0.06950608 -0.41409194
S3     Red    S 1072.672 0.41374648  0.19347947
S11    Red    S 1396.400 0.83443026 -0.04992459
S21    Red    S 1281.132 0.87777629  0.03674259
>

生成最终表的完整脚本是:

set.seed(9108171) # for reproducibility
gender <- rep(c("F","M", "O"),40)
status <- c(rep("Red",60),rep("Blue",60))
x <- round(rnorm(120,mean = 6,sd = 2),1)
y <- round(rnorm(120,mean = 8,sd = 1),1)

df <- data.frame(gender,status, x, y)

# filter red
library(dplyr)
red_status <- filter(df,status == "Red")
cor_red <- by(red_status, red_status$gender,
              FUN = function(df) cor.test(df$x, df$y, method = "spearman"))

# extract the required data
theResults <- lapply(c("F","M","O"),function(x){
  aTest <- cor_red[[x]]
  data.frame(status = "Red",
             test = names(aTest$statistic),
             value = aTest$statistic,
             p_value = aTest$p.value,
             rho = aTest$estimate)
})

# rbind the results into a single data frame
redResults <- do.call(rbind,theResults)
redResults

blue_status <- filter(df,status == "Blue")
cor_blue<- by(blue_status, blue_status$gender,
              FUN = function(df) cor.test(df$x, df$y, method = "spearman"))

# extract the required data
theResults <- lapply(c("F","M","O"),function(x){
  aTest <- cor_blue[[x]]
  data.frame(status = "Blue",
             test = names(aTest$statistic),
             value = aTest$statistic,
             p_value = aTest$p.value,
             rho = aTest$estimate)
})

# rbind the results into a single data frame
blueResults <- do.call(rbind,theResults)
rbind(blueResults,redResults)

我认识到我可以将重复的代码抽象成一个支持 function 以减少解决方案所需的总代码行数,但这留给读者作为一个微不足道的练习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM