尝试用 purrr::map_dbl 替换循环并使用 corrr::correlate

Trying to replace a loop with purrr::map_dbl and using corrr::correlate

我试图找到分组变量中所有变量的相关性。具体来说,我正在尝试使用 purrr 来替换我一直在使用的循环。但是我有点卡住了,部分原因是我想在对感兴趣的向量应用时使用两个函数。例如:

## load packages
library(corrr)
library(dplyr)
library(purrr)

没有任何组这工作正常(这是我想做的事情的基础):

iris %>%
  select(-Species) %>%
  correlate() %>%
  stretch()

但是当我尝试将其分组时,我遇到了困难:

iris %>%
  group_by(Species) %>%
  correlate() %>%
  stretch()

Error in stats::cor(x = x, y = y, use = use, method = method) : 'x' must be numeric

所以我的想法是使用 purrr... 似乎正是我使用它的地方吧?

iris %>%
  split(.$Species) %>%
  map_dbl(~correlate) ## then how do i incorporate `stretch()`

Error: Can't coerce element 1 from a closure to a double

显然这是错误的,但我不确定我应该如何在这里应用 map_*...

这是我要替换的循环,它确实提供了正确的输出,但我宁愿不使用它 - 它不如 purrr 方法灵活:

Species <- unique(iris$Species)
df <- c()
for(i in seq_along(Species)){
  u <- iris %>%
    filter(Species == Species[i]) %>%
    select(-Species) %>%
    correlate() %>%
    stretch() %>%
    mutate(Species = Species[i])

  df <- rbind(df, u)
}

df

# A tibble: 48 x 4
              x            y         r Species
          <chr>        <chr>     <dbl>  <fctr>
 1 Sepal.Length Sepal.Length        NA  setosa
 2 Sepal.Length  Sepal.Width 0.7425467  setosa
 3 Sepal.Length Petal.Length 0.2671758  setosa
 4 Sepal.Length  Petal.Width 0.2780984  setosa
 5  Sepal.Width Sepal.Length 0.7425467  setosa
 6  Sepal.Width  Sepal.Width        NA  setosa
 7  Sepal.Width Petal.Length 0.1777000  setosa
 8  Sepal.Width  Petal.Width 0.2327520  setosa
 9 Petal.Length Sepal.Length 0.2671758  setosa
10 Petal.Length  Sepal.Width 0.1777000  setosa

所以总而言之,当我需要使用两个函数时,有人能概述一下如何使用 purrr 吗?换句话说,如何替换上面的循环?

您需要使用 group_by %>% do 更灵活的摘要语法,其中在 do 中,您可以使用 . 访问每个子组并应用 correlatestretch就像一个普通的数据框:

library(corrr)
library(dplyr)

iris %>% group_by(Species) %>% do(
    select(., -Species) %>% correlate() %>% stretch()
)

# A tibble: 48 x 4
# Groups:   Species [3]
#   Species            x            y         r
#    <fctr>        <chr>        <chr>     <dbl>
# 1  setosa Sepal.Length Sepal.Length        NA
# 2  setosa Sepal.Length  Sepal.Width 0.7425467
# 3  setosa Sepal.Length Petal.Length 0.2671758
# 4  setosa Sepal.Length  Petal.Width 0.2780984
# 5  setosa  Sepal.Width Sepal.Length 0.7425467
# 6  setosa  Sepal.Width  Sepal.Width        NA
# 7  setosa  Sepal.Width Petal.Length 0.1777000
# 8  setosa  Sepal.Width  Petal.Width 0.2327520
# 9  setosa Petal.Length Sepal.Length 0.2671758
#10  setosa Petal.Length  Sepal.Width 0.1777000
# ... with 38 more rows

使用 purrr,您可以先将数据嵌套在每个组下,然后 map 覆盖它:

library(purrr)
library(tidyr)
library(dplyr)

iris %>% 
    group_by(Species) %>% nest() %>% 
    mutate(data = map(data, compose(stretch, correlate))) %>% 
    unnest()

# A tibble: 48 x 4
#   Species            x            y         r
#    <fctr>        <chr>        <chr>     <dbl>
# 1  setosa Sepal.Length Sepal.Length        NA
# 2  setosa Sepal.Length  Sepal.Width 0.7425467
# 3  setosa Sepal.Length Petal.Length 0.2671758
# 4  setosa Sepal.Length  Petal.Width 0.2780984
# 5  setosa  Sepal.Width Sepal.Length 0.7425467
# 6  setosa  Sepal.Width  Sepal.Width        NA
# 7  setosa  Sepal.Width Petal.Length 0.1777000
# 8  setosa  Sepal.Width  Petal.Width 0.2327520
# 9  setosa Petal.Length Sepal.Length 0.2671758
#10  setosa Petal.Length  Sepal.Width 0.1777000
# ... with 38 more rows