我正打算替换一些使用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"))
答案 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"))
-输出
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()
列。