Спирман корреляция по группам в R - PullRequest
8 голосов
/ 09 января 2012

Как рассчитать корреляцию Спирмена по группам в R. Я нашел следующую ссылку, говорящую о корреляции Пирсона по группам. Но когда я попытался заменить тип на spearman, он не работает.

https://stats.stackexchange.com/questions/4040/r-compute-correlation-by-group

Ответы [ 4 ]

18 голосов
/ 09 января 2012

Как насчет этого для базового решения R:

df <- data.frame(group = rep(c("G1", "G2"), each = 10),
                 var1 = rnorm(20),
                 var2 = rnorm(20))

r <- by(df, df$group, FUN = function(X) cor(X$var1, X$var2, method = "spearman"))
# df$group: G1
# [1] 0.4060606
# ------------------------------------------------------------ 
# df$group: G2
# [1] 0.1272727

И затем, если вы хотите получить результаты в виде data.frame:

data.frame(group = dimnames(r)[[1]], corr = as.vector(r))
#   group      corr
# 1    G1 0.4060606
# 2    G2 0.1272727

РЕДАКТИРОВАТЬ : Если вы предпочитаете решение на основе plyr, вот оно:

library(plyr)
ddply(df, .(group), summarise, "corr" = cor(var1, var2, method = "spearman"))
5 голосов
/ 09 января 2012

Вот еще один способ сделать это:

# split the data by group then apply spearman correlation
# to each element of that list
j <- lapply(split(df, df$group), function(x){cor(x[,2], x[,3], method = "spearman")})

# Bring it together
data.frame(group = names(j), corr = unlist(j), row.names = NULL)

Сравнение моего метода, метода Джоша и решения plyr с использованием rbenchmark:

Dason <- function(){
    # split the data by group then apply spearman correlation
    # to each element of that list
    j <- lapply(split(df, df$group), function(x){cor(x[,2], x[,3], method = "spearman")})

    # Bring it together
    data.frame(group = names(j), corr = unlist(j), row.names = NULL)
}

Josh <- function(){
    r <- by(df, df$group, FUN = function(X) cor(X$var1, X$var2, method = "spearman"))
    data.frame(group = attributes(r)$dimnames[[1]], corr = as.vector(r))
}

plyr <- function(){
    ddply(df, .(group), summarise, "corr" = cor(var1, var2, method = "spearman"))
}


library(rbenchmark)
benchmark(Dason(), Josh(), plyr())

, который дает вывод

> benchmark(Dason(), Josh(), plyr())
     test replications elapsed relative user.self sys.self user.child sys.child
1 Dason()          100    0.19 1.000000      0.19        0         NA        NA
2  Josh()          100    0.24 1.263158      0.22        0         NA        NA
3  plyr()          100    0.51 2.684211      0.52        0         NA        NA

Так что, похоже, мой метод немного быстрее, но ненамного.Я думаю, что метод Джоша немного более интуитивно понятен.Решение plyr проще всего кодировать, но оно не самое быстрое (но оно гораздо удобнее)!

3 голосов
/ 19 сентября 2012

Если вы хотите эффективное решение для большого числа групп, тогда вам нужно выбрать data.table.

library(data.table)
DT <- as.data.table(df)
setkey(DT, group)
DT[,list(corr = cor(var1,var2,method = 'spearman')), by = group]
0 голосов
/ 05 июля 2019

очень старый вопрос, но это решение tidy & broom чрезвычайно простое.Таким образом, я должен разделить подход:

set.seed(123)
df <- data.frame(group = rep(c("G1", "G2"), each = 10),
                 var1 = rnorm(20),
                 var2 = rnorm(20))

library(tidyverse)
library(broom)

df  %>% 
  group_by(group) %>%
  summarize(correlation = cor(var1, var2,, method = "sp"))
# A tibble: 2 x 2
  group correlation
  <fct>       <dbl>
1 G1        -0.200 
2 G2         0.0545

# with pvalues and further stats
df %>% 
  nest(-group) %>% 
  mutate(cor=map(data,~cor.test(.x$var1, .x$var2, method = "sp"))) %>%
  mutate(tidied = map(cor, tidy)) %>% 
  unnest(tidied, .drop = T)
# A tibble: 2 x 6
  group estimate statistic p.value method                          alternative
  <fct>    <dbl>     <dbl>   <dbl> <chr>                           <chr>      
1 G1     -0.200        198   0.584 Spearman's rank correlation rho two.sided  
2 G2      0.0545       156   0.892 Spearman's rank correlation rho two.sided 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...