在R中创建多个绘图图形时,如何从group_by(dplyr)变量分配图形标题



长期读者,这里是首次提问者。

我正在使用plotly和dplyr的group_by(group_by变量的每个级别一个图形)创建多个绘图。

在下面的例子中,我每年创建一个绘图(group_by变量),我想将年份指定为图形标题。但是,我不知道如何使用数据帧(或tibble)中存储的值来分配标题。

非常感谢您的任何建议!非常感谢。

require(dplyr)
require(plotly)
# creating data table
d = tibble(year=rep(2016:2017,2), type=c(1,1,2,2), amount=1:4)
d
# creating 2 figures, grouped by year (one for each year).  
# Using the same title for each figure (this code works).
chart = d %>% 
group_by(year) %>%
do(plots = plot_ly(., values = ~amount, type = 'pie') %>% layout(title="Great Title") )
# printing first plot
chart$plots[1][[1]]
# I'd like the title of each figure to be the year.  
# I get an error when I try to assign the title with the year variable.
chart.title = d %>% 
group_by(year) %>%
do(plots = plot_ly(., values = ~amount, type = 'pie') %>% layout(title=year) )


在tidyverse中,purrr是迭代元素的工具,也是函数编程的助手。将purrr和嵌套data.frame与列表列相结合是一个强大的工作流。然后可以执行与group_bydo相同的操作,但它更强大
我在哪里读到它可以取代dplyr::do

以下是您的问题的解决方案tidyverse方式

library(dplyr, warn.conflicts = F)
library(plotly)
# for iteration and fonctionnal programming
library(purrr)
# for nesting dataframe
library(tidyr)
# creating  the data
d <- tibble(year=rep(2016:2017,2), type=c(1,1,2,2), amount=1:4)
d
#> # A tibble: 4 x 3
#>    year  type amount
#>   <int> <dbl>  <int>
#> 1  2016     1      1
#> 2  2017     1      2
#> 3  2016     2      3
#> 4  2017     2      4

如果你想按年份工作,你可以按年份嵌套数据,并有一个tibble,每年有一行和一个名为data的列表列,其中每个元素是tibble,是上一年的初始数据的子集线路

nested_data <- d %>% 
nest(-year)
nested_data
#> # A tibble: 2 x 2
#>    year             data
#>   <int>           <list>
#> 1  2016 <tibble [2 x 2]>
#> 2  2017 <tibble [2 x 2]>

purrrmap系列的结合允许您在列表中进行迭代。结合dplyr动词,我们将添加一列,其中包含CCD_ 10图。map2采用两个参数,列表列数据和列年份并应用一个动作我们得到一个列表,结果我们将存储在另一个名为plots 的列表列中

charts <- nested_data %>%
mutate(plots = map2(data, year, ~ plot_ly(.x, values = ~amount, type = 'pie') %>% layout(title = .y)))

您可以继续使用此tibble。计算出这些图与您的数据一起存储。

charts
#> # A tibble: 2 x 3
#>    year             data        plots
#>   <int>           <list>       <list>
#> 1  2016 <tibble [2 x 2]> <S3: plotly>
#> 2  2017 <tibble [2 x 2]> <S3: plotly>

要手动打印绘图,您可以访问

charts$plots[1]
#> [[1]]

您可以使用purrr迭代列表列并打印所有绘图#这将在RStudio查看器中打印绘图print_plot<-图表%>%选择(绘图)%>%行走(打印)

总之,在tidyverse生态系统中,可以用nestpurrr功能替换group_bydo

charts <- d %>%
nested(- year) %>%
mutate(plots = map2(data, year, ~ plot_ly(.x, values = ~amount, type = 'pie') %>% layout(title = .y)))

这应该不复杂,因为您可以通过.$year访问本地年份变量,例如通过.$year[1]访问唯一年份(因为每组中的year都是常数)。

但是您遇到了一个问题,因为您在do外部和内部双重使用了%>%管道符号,这使得.无法引用分组数据,而是引用了当前绘图。你可以通过取消嵌套来解决这个问题:

chart = d %>% 
group_by(year) %>%
do(plots = layout(
plot_ly(., values = ~amount, type = 'pie'), 
title = paste('Chart of year', .$year[1]))
)
chart$plots[1][[1]]