【问题标题】:Correlation using funs in dplyr在 dplyr 中使用 funs 进行相关性
【发布时间】:2016-02-20 00:25:49
【问题描述】:

我想使用 dplyr 查找 data.frame 中各个列的排名相关性。

我确信这个问题有一个简单的解决方案,但我认为问题在于我在使用 cor 函数时无法在 dplyr 中的 summarise_each_ 中使用两个输入。

对于以下df:

df <- data.frame(Universe=c(rep("A",5),rep("B",5)),AA.x=rnorm(10),BB.x=rnorm(10),CC.x=rnorm(10),AA.y=rnorm(10),BB.y=rnorm(10),CC.y=rnorm(10))

我想获得所有 .x 和 .y 组合之间的排名相关性。我在下面的函数中看到的问题????

cor <- df %>% group_by(Universe) %>% 
summarize_each_(funs(cor(.,method = 'spearman',use = "pairwise.complete.obs")),????)

我希望 cor 只包含相关对:每个 Universe 的 AA.x.AA.y 、 AA.x,BB.y, ...。

请帮忙!

【问题讨论】:

  • 基本解决方案可以是lapply(split(df[-1], df$Universe), function(x) cor(x[grepl("\\.x", names(x))], x[grepl("\\.y", names(x))], method = 'spearman', use = "pairwise.complete.obs"))
  • 这很好用,谢谢。但我有一个非常大的数据集,使用 dplyr 方法绝对是更可取的。我自己的基本 R 解决方案需要很长时间..
  • 相关的questiondata.table 解决方案,如果您对不同的库开放
  • 您希望输出是什么样的?

标签: r dplyr


【解决方案1】:

另一种方法是只调用一次cor 函数,因为这将计算所有必需的相关性。重复调用cor 可能是大型数据集的性能问题。执行此操作并提取带有标签的相关对的代码如下所示:

#
# calculate correlations and display in matrix format
#
cor_matrix <- df %>% group_by(Universe) %>%
              do(as.data.frame(cor(.[,-1], method="spearman", use="pairwise.complete.obs")))
#
# to add row names
#
cor_matrix1 <- cor_matrix %>%  
              data.frame(row=rep(colnames(.)[-1], n_groups(.))) 
#
# calculate correlations and display in column format
#
num_col=ncol(df[,-1])
out_indx <-  which(upper.tri(diag(num_col))) 
cor_cols <- df %>% group_by(Universe) %>%
            do(melt(cor(.[,-1], method="spearman", use="pairwise.complete.obs"), value.name="cor")[out_indx,])

【讨论】:

  • 这是解决我的问题的最快方法。杰出的。在这个例子中使用 do 效果很好,即使对我来说使用起来不太直观!
【解决方案2】:

下面是我的问题的成功(时间)解决方案:

d <- df %>% gather(R1,R1v,contains(".x")) %>% gather(R2,R2v,contains(".y"),-Universe) %>% group_by(Universe,R1,R2) %>% 
       summarize(ICAC = cor(x=R1v, y=R2v,method = 'spearman',use = "pairwise.complete.obs")) %>% 
       unite(Pair, R1, R2, sep="_")

虽然在本例中为 0.005 毫秒,但添加数据会增加时间。

【讨论】:

    【解决方案3】:

    试试这个:

    library(data.table)                                           # needed for fast melt
    setDT(df)                                                     # sets by reference, fast
    mdf <- melt(df[, id := 1:.N], id.vars = c('Universe','id'))
    
    mdf %>% 
      mutate(obs_set = substr(variable, 4, 4) ) %>%               # ".x" or ".y" subgroup
      full_join(.,., by=c('Universe', 'obs_set', 'id')) %>%       # see notes
      group_by(Universe, variable.x, variable.y) %>%
      filter(variable.x != variable.y) %>%
      dplyr::summarise(rank_corr = cor(value.x, value.y, 
                       method='spearman', use='pairwise.complete.obs'))
    

    生产:

       Universe variable.x variable.y rank_corr
         (fctr)     (fctr)     (fctr)     (dbl)
    1         A       AA.x       BB.x      -0.9
    2         A       AA.x       CC.x      -0.9
    3         A       BB.x       AA.x      -0.9
    4         A       BB.x       CC.x       0.8
    5         A       CC.x       AA.x      -0.9
    6         A       CC.x       BB.x       0.8
    7         A       AA.y       BB.y      -0.3
    8         A       AA.y       CC.y       0.2
    9         A       BB.y       AA.y      -0.3
    10        A       BB.y       CC.y      -0.3
    ..      ...        ...        ...       ...
    

    解释:

    1. Melt:将表格转换为长格式,每次观察一行。要在dplyr 链中进行融化,我相信您必须使用tidyr::gather,所以选择您的依赖项。使用data.table 更快且不难理解。该步骤还为每个观察创建一个 id,从 1 到 nrow(df)。其余的就像你想要的那样在dplyr 中。

    2. 完全连接:将熔化的表连接到自身,以根据常见的Universe 和观察id 从所有变量配对创建配对观察结果(编辑:现在是'.x' 或'.y '子组)

    3. 过滤器:我们不需要将观察结果与自身配对,我们知道这些相关性 = 1。如果您想将它们包含在相关矩阵或其他内容中,请注释掉这一步。

    4. 使用 Spearman 相关性进行总结。请注意,您应该使用dplyr::summarise,因为如果您还加载了plyr,您可能会accidentally 调用plyr::summarise

    【讨论】:

    • 您的解决方案产生了预期的结果,谢谢。我最终弄清楚的方式要快一些。我这样做如下:d % gather(R1,R1v,contains(".x")) %>% gather(R2,R2v,contains(".y"),-Universe) %>% group_by(Universe,R1,R2) %>% summarise(ICAC = cor(x=R1v, y=R2v,method = 'spearman',use = "pairwise.complete.obs")) %>% unity(Pair, R1 , R2, sep="_")
    • @Nick 有趣,我很惊讶 2x gather 在您的示例中被证明更快。感谢您的回复。如果运行时是您的第一个关注点,那么您绝对应该考虑data.tableplyr 的并行使用。提出最快的dplyr 解决方案可能就像找到世界上最短的巨人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    相关资源
    最近更新 更多