我是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")))
您是否能够帮助澄清我在使用此代码时做错了什么,或者我是否需要使用其他方法来完成此任务?
答案 0 :(得分:5)
有几种方法可以在R中实现。dplyr
或更一般地tidyverse
是一组能够达到预期效果的流行工具。这些工具的主要区别在于管道%>%
,它提供了一种从左到右而不是从内到外编写代码的方法(或者在环境中创建一堆中间对象)。尽管管道可以与基础R一起使用,但其受欢迎程度来自于dplyr
。
以下是mtcars数据集的几个示例。关键功能是do
和map
,它们非常通用。我建议运行?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