R:"synchronizing" R 中的绘图

R: "synchronizing" plots in R

我正在使用 R 编程语言。我写了下面的代码来制作一个交互式时间序列“滑块”

 library(dplyr)
    library(ggplot2)
    library(shiny)
    library(plotly)
    library(htmltools)
    
    library(dplyr)
#generate data
set.seed(123)

var = rnorm(731, 100,25)
date= seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
data = data.frame(var,date)

vals <- 90:100
combine <- vector('list', length(vals))
count <- 0
for (i in vals) {
 
  data$var_i = i
  data$new_var_i = ifelse(data$var >i,1,0)
 
  #percent of observations greater than i (each month)
  aggregate_i = data %>%
    mutate(date = as.Date(date)) %>%
    group_by(month = format(date, "%Y-%m")) %>%
    summarise( mean = mean(new_var_i))
 
  #combine files together
 
  aggregate_i$var = i
  aggregate_i$var = as.factor(aggregate_i$var)
 
  count <- count + 1
  combine[[count]] <- aggregate_i
 
}

result_1 <- bind_rows(combine)
result_1$group = "group_a"
result_1$group = as.factor(result_1$group)

######

var = rnorm(731, 85,25)
date= seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
data = data.frame(var,date)

vals <- 90:100
combine <- vector('list', length(vals))
count <- 0
for (i in vals) {
 
  data$var_i = i
  data$new_var_i = ifelse(data$var >i,1,0)
 
  #percent of observations greater than i (each month)
  aggregate_i = data %>%
    mutate(date = as.Date(date)) %>%
    group_by(month = format(date, "%Y-%m")) %>%
    summarise( mean = mean(new_var_i))
 
  #combine files together
 
  aggregate_i$var = i
  aggregate_i$var = as.factor(aggregate_i$var)
 
  count <- count + 1
  combine[[count]] <- aggregate_i
 
}

result_2 <- bind_rows(combine)
result_2$group = "group_b"
result_2$group = as.factor(result_2$group)

#combine all files

final = rbind(result_1, result_2)

gg <-ggplot(final, aes(frame = var, color = group)) + geom_line(aes(x=month, y=mean, group=1))+ theme(axis.text.x = element_text(angle=90)) + ggtitle("title")

gg = ggplotly(gg)

从这里开始,我想制作 3 个额外的图表,对应于滑块当前所在位置的“var”值。我在下面对此进行了说明(对于 var = 90):

这是制作这 3 个附加图表所需的 R 代码(对于 var = 90):

#### filter for var = 90

a90 = final %>% 
  filter(var == 90)

a90 = a90 %>%
    group_by(group) %>%
    summarise( avg = mean(mean))

##bar plot

plot<-ggplot(data=a90, aes(x=group, y=avg)) +
  geom_bar(stat="identity") + ggtitle("bar plot")

bar_plotly <- ggplotly(plot)


#pie chart 
 Pie = ggplot(a90, aes(x="", y=(1-avg), fill=group)) +
      geom_bar(stat="identity", width=1) +
      coord_polar("y", start=0) +ggtitle( "Pie Chart") + scale_fill_brewer(palette="Blues")+
  theme_minimal()

#for some reason this does not work
pie_plotly = ggplotly(Pie)



#table

fig <- plot_ly(
  type = 'table',
  columnwidth = c(100, 100),
  columnorder = c(0, 1),
  header = list(
    values = c("average","group"),
    align = c("center", "center"),
    line = list(width = 1, color = 'black'),
    fill = list(color = c("grey", "grey")),
    font = list(family = "Arial", size = 14, color = "white")
  ),
  cells = list(
    values = rbind(a90$avg, a90$group),
    align = c("center", "center"),
    line = list(color = "black", width = 1),
    font = list(family = "Arial", size = 12, color = c("black"))
  ))

fig

我试图将所有图表放在一起,但这没有用:

doc <- htmltools::tagList(
  div(gg, style = "float:left;width:50%;"),
  div(bar_plotly,style = "float:left;width:50%;"),
  div(fig, style = "float:left;width:50%;"))

htmltools::save_html(html = doc, file = "final.html")

Error in as.vector(x, "character") : 
  cannot coerce type 'environment' to vector of type 'character'

有人可以告诉我这是否可以在用户滑动第一个图表的滑块时更新其他图表?

谢谢

> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19041)

Matrix products: default

locale:
[1] LC_COLLATE=English_Canada.1252  LC_CTYPE=English_Canada.1252    LC_MONETARY=English_Canada.1252
[4] LC_NUMERIC=C                    LC_TIME=English_Canada.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.6.0       htmltools_0.5.1.1 dplyr_1.0.3       plotly_4.9.3      ggplot2_3.3.3    

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.6         later_1.1.0.1      pillar_1.4.7       compiler_4.0.3     RColorBrewer_1.1-2 tools_4.0.3       
 [7] digest_0.6.27      jsonlite_1.7.2     lifecycle_0.2.0    tibble_3.0.5       gtable_0.3.0       viridisLite_0.3.0 
[13] pkgconfig_2.0.3    rlang_0.4.10       cli_2.2.0          rstudioapi_0.13    crosstalk_1.1.1    yaml_2.2.1        
[19] fastmap_1.1.0      withr_2.4.1        httr_1.4.2         generics_0.1.0     vctrs_0.3.6        htmlwidgets_1.5.3 
[25] grid_4.0.3         tidyselect_1.1.0   glue_1.4.2         data.table_1.13.6  R6_2.5.0           fansi_0.4.2       
[31] purrr_0.3.4        tidyr_1.1.2        farver_2.0.3       magrittr_2.0.1     promises_1.1.1     scales_1.1.1      
[37] ellipsis_0.3.1     assertthat_0.2.1   xtable_1.8-4       mime_0.9           colorspace_2.0-0   httpuv_1.5.5      
[43] labeling_0.4.2     lazyeval_0.2.2     munsell_0.5.0      crayon_1.3.4 

根据plotly's tutorial, the way to combine different plots is to use subplot. By doing this, it also links the slider to all plots if you defined the frame argument in all plots (see ).

此外,对于这些更复杂的图,我认为直接在 plotly API 中工作总是比转换 ggplot

更安全
# create summary dataframe for bar chart and pie chart
df.summary <- final %>% group_by(group, var) %>%
  summarise( avg = mean(mean)) %>% ungroup()

# create line chart
gg <- final %>% 
  plot_ly(x = ~month, y = ~mean, frame=~var, color=~group, type = 'scatter', mode = 'lines', colors = 'Set1') %>% 
  layout(showlegend = F)

# create bar chart
bar_plotly <- df.summary %>% 
  plot_ly(x = ~group, y = ~avg, frame=~var, color=~group, ids=groups, type = 'bar', colors = 'Set1') %>% 
  layout(showlegend = F, yaxis = list(range = c(0, 0.7)))

# create pie chart
Pie <- df.summary %>% 
  plot_ly(values = ~avg, frame=~var, ids=groups, type = 'pie', domain = list(x = c(0.6, 1), y = c(0, 0.4)), colors = 'Set1') %>% 
  layout(showlegend = F)

# combine all of them into one interactive plot
subplot(gg, subplot(bar_plotly, Pie, nrows = 2), nrows = 1)

According to plotly,并非所有轨迹都完全支持动画。所以饼图中的过渡不会很平滑。

此外,我不认为你可以 link table 与当前的情节 API。

另一种选择是创建一个闪亮的应用程序,您可以在其中进行更多控制。