用dplyr :: group_split和purrr :: map_df

时间:2019-07-18 13:56:39

标签: r dplyr purrr

我正打算替换一些使用dplyr :: do的R代码,因为该功能将很快被弃用。我的许多工作都需要创建分层的CDF图。使用dply:do时,将我分层的变量作为变量传递到生成的数据帧,然后可以方便地用于绘图。

我有一个使用dplyr :: group_split和purrr :: map_df替换dplyr :: do的解决方案。但是,我在dplyr :: group_split中传递的变量未在结果数据框中命名。这使得绘制分层数据变得困难。如何确保在结果数据框中命名在dlyr :: group_split中传递的变量?

以下是一些代码,这些数据创建了我需要使用dplyr :: do:绘制的数据

library(dplyr)
library(purrr)
library(ggplot2)

# simulate data
dat <- tibble(
  strat = rep(letters[1:3], each = 33), 
  var   = rnorm(99, 0, 1))

# example 1 that works, but will be depricated 
test_dat_1 <- dat %>% 
  dplyr::select(strat, var) %>%
  dplyr::group_by(strat) %>%
  dplyr::do(data.frame(X = wtd.Ecdf(.[[2]])$x, 
                       Y = wtd.Ecdf(.[[2]])$ecdf*100))

# this is the target plot
p <- ggplot(test_dat_1, aes(X, Y, colour = strat))
p + geom_step()

这里是使用新的整洁和purrr函数创建数据的解决方案,但局限性在于最终数据帧中未提供我分层的变量,这使得绘制分层数据变得麻烦:

# replacement for 'do'
test_dat_2 <- dat %>%
  group_split(strat) %>%
  map_df(~wtd.Ecdf(.x$var),
         tibble::enframe(name = "X", value = "Y"))

2 个答案:

答案 0 :(得分:3)

假设wtd.Ecdf来自Hmisc,则输出为named list,可以使用as_tibble将其转换为两列数据集,与do的{​​{1}}解决方案中的'ecdf'列

mutate

现在,在绘图中使用它

library(dplyr)
library(purrr)
library(Hmisc)
library(ggplot2)
test_dat_2 <- dat %>% 
                 group_split(strat) %>% 
                 map_df(~ c(strat = first(.x$strat), wtd.Ecdf(.x$var)) %>% 
                              as_tibble %>%
                              mutate(ecdf = ecdf * 100)) %>%
                 rename_at(2:3, ~ c("X", "Y"))

-输出

enter image description here


p <- ggplot(test_dat_2, aes(X, Y, colour = strat)) p + geom_step() 之后,也可以选择

nest

答案 1 :(得分:2)

拆分的另一种选择是使用group_nest()进行嵌套。嵌套后,您可以在map()内进行mutate()

如果您想将所有组都绘制在一起,则可以从 tidyr unnest()

我在map()中写了一个匿名函数,而不是使用波浪号。

dat %>%
    group_nest(strat) %>%
    mutate(result = map(data, function(dat) {
        res = Hmisc::wtd.Ecdf(dat$var)
        data.frame(X = res$x, Y = res$ecdf*100)
        }) ) %>%
    tidyr::unnest(result)

# A tibble: 102 x 4
   strat data                   X     Y
   <chr> <list>             <dbl> <dbl>
 1 a     <tibble [33 x 1]> -1.88   0   
 2 a     <tibble [33 x 1]> -1.88   3.03
 3 a     <tibble [33 x 1]> -1.76   6.06
 4 a     <tibble [33 x 1]> -1.17   9.09
...

在嵌套之前,您可以根据需要在data调用中使用select()data = NULL摆脱mutate()列。