Pearson Correlation"分层"按分类变量

时间:2018-01-02 18:43:32

标签: r

我是R.的新手。

我有兴趣为我的数据计算Pearson Correlations。我已经成功地弄清楚如何计算我的数据集x和y中两个连续变量的相关性;但是,我希望"分层"相关性由第三个分类变量:状态。我希望能够说" x和y的相关系数/ p值是[State]中的[Result]。"

我已经尝试了位于dplyr包中的group_by方法,该方法位于cor.test(如下所示)中。我需要系数和p值,所以我一直在尝试使用cor.test方法。我也试过使用矩阵方法,但也不成功。

Data<-read.csv("PATHWAYNAME")
  library(dplyr)
  CCor<-cor.test(Data$x, Data$y,
          method=c("pearson"), group_by(State))
  CCor

我能够分别为每个状态运行每组值,以获得系数和p值;但是,我确信有一种更有效的方法可以完成这项任务。我的数据足够大,单独运行它们将非常繁琐。

提前感谢您的帮助!

更新 使用它作为极端截断的样本数据集,但同样代表我自己的变量,我想知道平均收入是否与列出的每个州的访问次数相关;也就是说,平均收入与阿拉巴马州的访问量有正相关或负相关吗?

>State  NumVis  AvgIncome
>IN       45        60000
>AL       100       56000
>AK       45        80000
>ME       89        54000
>NC       120       100000
>SC       356       43000
>ND       100       25000
>SD       63        20000
>MN       54        46000
>ID       85        55000

使用下面的代码运行此数据时,我的结果如下:

 CorrDat<-read.csv("File")
     CorrDat %>%
       group_by(State) %>%
        do(tidy(cor.test(CorrDat$NumVis, CorrDat$Income, method="pearson")))

Results

您是否能够帮助澄清我在使用此代码时做错了什么,或者我是否需要使用其他方法来完成此任务?

2 个答案:

答案 0 :(得分:5)

有几种方法可以在R中实现。dplyr或更一般地tidyverse是一组能够达到预期效果的流行工具。这些工具的主要区别在于管道%>%,它提供了一种从左到右而不是从内到外编写代码的方法(或者在环境中创建一堆中间对象)。尽管管道可以与基础R一起使用,但其受欢迎程度来自于dplyr

以下是mtcars数据集的几个示例。关键功能是domap,它们非常通用。我建议运行?do?map

library(tidyverse)

mtcars %>%
  group_by(cyl) %>%
  summarize(cor = cor(mpg, disp))
#output
# A tibble: 3 x 2
    cyl correlation
  <dbl>       <dbl>
1     4  -0.8052361
2     6   0.1030827
3     8  -0.5197670

另一种方式是:

mtcars  %>% 
  group_by(cyl) %>%
  do(cor = cor(.$mpg, .$disp)) %>%
  unnest()

或更多变量:

mtcars  %>% 
  group_by(cyl) %>%
  do(cor = as.data.frame(cor(.[,-2]) )) %>%
  unnest() 

cor.test的一个例子:

library(broom)

mtcars  %>% 
  group_by(cyl)  %>% 
  do(tidy(cor.test(.$mpg, .$disp))) 
#output
    cyl   estimate  statistic     p.value parameter   conf.low   conf.high                               method alternative
  <dbl>      <dbl>      <dbl>       <dbl>     <int>      <dbl>       <dbl>                               <fctr>      <fctr>
1     4 -0.8052361 -4.0740206 0.002782827         9 -0.9474526 -0.39724826 Pearson's product-moment correlation   two.sided
2     6  0.1030827  0.2317344 0.825929685         5 -0.7046776  0.79446840 Pearson's product-moment correlation   two.sided
3     8 -0.5197670 -2.1075838 0.056774876        12 -0.8232990  0.01492976 Pearson's product-moment correlation   two.sided

还有另一种使用purrr :: map的方式:

mtcars  %>% 
  split(.$cyl)  %>% 
  map(~cor.test(.x$mpg, .x$disp))

给出一个列表,可以使用相同或另一个map函数进行操作:

mtcars  %>% 
  split(.$cyl)  %>% 
  map(~cor.test(.x$mpg, .x$disp)) %>%
  map_dbl("p.value")
#output:
          4           6           8 
0.002782827 0.825929685 0.056774876 

提取系数:

mtcars  %>% 
  split(.$cyl)  %>% 
  map(~cor.test(.x$mpg, .x$disp)) %>%
  map(~data.frame(cor = .x$estimate, p = .x$p.value)) #check also `map_dfr` and `map_dfc`

#output
$`4`
           cor           p
cor -0.8052361 0.002782827

$`6`
          cor         p
cor 0.1030827 0.8259297

$`8`
          cor          p
cor -0.519767 0.05677488

更新:回答更新的问题:

问题是您如何指定do来电。这是正确的:

df %>%
  group_by(State) %>%
  do(tidy(cor.test(.$NumVis, .$AvgIncome, method="pearson")))

其中.表示前一个管道传递的数据。在发布的示例中,结果为:

Error in cor.test.default(.$NumVis, .$AvgIncome, method = "pearson") : 
not enough finite observations

这是合理的,考虑到每组仅进行1次观察

你做的是:

CorrDat<-read.csv("File")
     CorrDat %>%
       group_by(State) %>%
        do(tidy(cor.test(CorrDat$NumVis, CorrDat$Income, method="pearson")))

将整个CorrDat集传递给do函数,以便它执行与组相同的操作次数。

%>%管道假定传递的数据将用作以下函数中的第一个参数,如果它不应该将数据称为.。您可以执行.$column.[,2]等操作。

答案 1 :(得分:0)

使用base r,您可以使用by

,例如,在missuse的帖子中复制其中一个例子:

do.call(rbind,
        by(mtcars, mtcars$cyl, FUN = function(x) cor.test(x$mpg, x$disp, data = x)))

statistic parameter p.value     estimate   null.value alternative method                                 data.name          conf.int 
4 -4.074021 9         0.002782827 -0.8052361 0          "two.sided" "Pearson's product-moment correlation" "x$mpg and x$disp" Numeric,2
6 0.2317344 5         0.8259297   0.1030827  0          "two.sided" "Pearson's product-moment correlation" "x$mpg and x$disp" Numeric,2
8 -2.107584 12        0.05677488  -0.519767  0          "two.sided" "Pearson's product-moment correlation" "x$mpg and x$disp" Numeric,2