Ifeanyi commited on
Commit
3a638e2
·
verified ·
1 Parent(s): 53e73c5

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +170 -49
app.R CHANGED
@@ -1,58 +1,179 @@
1
  library(shiny)
2
  library(bslib)
3
- library(dplyr)
4
- library(ggplot2)
5
-
6
- df <- readr::read_csv("penguins.csv")
7
- # Find subset of columns that are suitable for scatter plot
8
- df_num <- df |> select(where(is.numeric), -Year)
9
-
10
- ui <- page_sidebar(
11
- theme = bs_theme(bootswatch = "minty"),
12
- title = "Penguins explorer",
13
- sidebar = sidebar(
14
- varSelectInput("xvar", "X variable", df_num, selected = "Bill Length (mm)"),
15
- varSelectInput("yvar", "Y variable", df_num, selected = "Bill Depth (mm)"),
16
- checkboxGroupInput("species", "Filter by species",
17
- choices = unique(df$Species), selected = unique(df$Species)
18
- ),
19
- hr(), # Add a horizontal rule
20
- checkboxInput("by_species", "Show species", TRUE),
21
- checkboxInput("show_margins", "Show marginal plots", TRUE),
22
- checkboxInput("smooth", "Add smoother"),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  ),
24
- plotOutput("scatter")
 
 
 
 
 
 
 
25
  )
26
 
27
- server <- function(input, output, session) {
28
- subsetted <- reactive({
29
- req(input$species)
30
- df |> filter(Species %in% input$species)
31
- })
32
 
33
- output$scatter <- renderPlot(
34
- {
35
- p <- ggplot(subsetted(), aes(!!input$xvar, !!input$yvar)) +
36
- theme_light() +
37
- list(
38
- theme(legend.position = "bottom"),
39
- if (input$by_species) aes(color = Species),
40
- geom_point(),
41
- if (input$smooth) geom_smooth()
42
- )
43
-
44
- if (input$show_margins) {
45
- margin_type <- if (input$by_species) "density" else "histogram"
46
- p <- p |> ggExtra::ggMarginal(
47
- type = margin_type, margins = "both",
48
- size = 8, groupColour = input$by_species, groupFill = input$by_species
49
- )
50
- }
51
-
52
- p
53
- },
54
- res = 100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  )
 
 
 
 
 
 
 
 
 
 
 
56
  }
57
 
58
- shinyApp(ui, server)
 
 
1
  library(shiny)
2
  library(bslib)
3
+ library(bs4Dash)
4
+ library(ellmer)
5
+ library(querychat)
6
+ library(shinythemes)
7
+ library(gapminder)
8
+ library(highcharter)
9
+ library(reactable)
10
+ library(shinychat)
11
+
12
+ Sys.setenv(GOOGLE_API_KEY = "AIzaSyAau0taEMZoOPtqDS-K_ZxiN6lycfcJ_pE")
13
+
14
+ # get Gemini api key
15
+ api_key = Sys.getenv("GOOGLE_API_KEY")
16
+
17
+ # create data of the first 500 rows in gapminder
18
+ gdp_data <- gapminder
19
+
20
+
21
+ # initialize querychat with mtcars dataset and Gemini chat function
22
+ querychat_config <- querychat_init(gdp_data,
23
+ create_chat_func = purrr::partial(ellmer::chat_google_gemini, model = "gemini-2.0-flash"),
24
+ greeting = "")
25
+
26
+ # define the UI of the dashboard
27
+ ui <- tabsetPanel(
28
+ id = "tabs",
29
+ type = "pills",
30
+ tabPanel(
31
+ id = "query-tab",
32
+ title = strong("Data Query"),
33
+ icon = icon("chart-line",lib = "font-awesome",),
34
+ page_sidebar(
35
+ # hover bounce effect of value boxes
36
+ tags$head(
37
+ tags$style(HTML("
38
+ .bounce-hover:hover {
39
+ animation: bounce 0.6s infinite alternate;
40
+ }
41
+
42
+ @keyframes bounce {
43
+ from {
44
+ transform: translateY(0);
45
+ }
46
+ to {
47
+ transform: translateY(-10px);
48
+ }
49
+ }
50
+ "))
51
+ ),
52
+ sidebar = querychat_sidebar("chat",width = "25%"),
53
+ # to change div background color on hover: onmouseover = "this.style.backgroundColor='mediumseagreen';", onmouseout="this.style.backgroundColor='DodgerBlue';". In style = "cursor: pointer;
54
+ fluidRow(column(4,tags$div(class = "bounce-hover",valueBoxOutput("GDP"), style = "text-align:center; font-size: 20px; font-weight: bold;color:black;")),
55
+ column(4,tags$div(class = "bounce-hover",valueBoxOutput("Population"), style = "text-align:center; font-size: 20px; font-weight: bold;")),
56
+ column(4,tags$div(class = "bounce-hover",valueBoxOutput("LifeExp"),style = "text-align:center; font-size: 20px; font-weight: bold;"))),
57
+ fluidRow(column(6,highchartOutput("line",width = "98%")),
58
+ column(6,highchartOutput("column",width = "98%"))),
59
+ fluidRow(reactable::reactableOutput("table",width = "100%"))
60
+ )
61
  ),
62
+ tabPanel(
63
+ id = "chat-tab",
64
+ title = strong("EconoBot"),
65
+ icon = icon("robot",lib = "font-awesome"),
66
+ h3(strong("🤖 EconoBot"),style="text-align:center;color:DodgerBlue;"),
67
+ h5(strong("Answers your economic and financial questions"),style="text-align:center;color:#37474f;"),
68
+ chat_ui("gemini_chat",placeholder = "Type your message here...")
69
+ )
70
  )
71
 
72
+ # define the server logic required to interact with the data
73
+ server <- function(input, output) {
 
 
 
74
 
75
+ # create a querychat object using the config from step 1.
76
+ query_chat <- querychat_server("chat", querychat_config)
77
+
78
+ output$table <- reactable::renderReactable({
79
+ reactable::reactable(query_chat$df(),
80
+ bordered = T,
81
+ compact = T,
82
+ highlight = T,
83
+ striped = T,
84
+ searchable = T,
85
+ filterable = T,
86
+ defaultColDef = colDef(align = "center"),
87
+ theme = reactable::reactableTheme(
88
+ stripedColor = "#0091ea",
89
+ borderColor = "#0091ea",
90
+ borderWidth = 3
91
+ ))
92
+ })
93
+
94
+ output$line <- renderHighchart({
95
+ req(query_chat$df())
96
+ my_colors <- c("Africa" = "#1f77b4", "Asia" = "#ff7f0e", "Europe" = "#2ca02c",
97
+ "Americas" = "#d62728", "Oceania" = "#9467bd")
98
+
99
+ hchart(query_chat$df(),
100
+ type = "line",
101
+ hcaes(x = year, y = pop, group = continent)) |>
102
+ hc_colors(unname(my_colors)) |>
103
+ hc_title(text = "Population Per Continent or Country")
104
+ })
105
+
106
+ output$column <- renderHighchart({
107
+ req(query_chat$df())
108
+ my_colors <- c("Africa" = "#1f77b4", "Asia" = "#ff7f0e", "Europe" = "#2ca02c",
109
+ "Americas" = "#d62728", "Oceania" = "#9467bd")
110
+
111
+ hchart(query_chat$df(),
112
+ type = "column",
113
+ hcaes(x = year, y = gdpPercap, group = continent)) |>
114
+ hc_colors(unname(my_colors)) |>
115
+ hc_title(text = "GDP Per Capita Per Continent or Country")
116
+ })
117
+
118
+ output$GDP <- renderValueBox({
119
+ req(query_chat$df())
120
+ valueBox(
121
+ value = round(mean(query_chat$df()$gdpPercap, na.rm = TRUE), 2),
122
+ color = "success",
123
+ icon = icon("dollar"),
124
+ elevation = 4,
125
+ width = 4,
126
+ subtitle = " ",
127
+ footer = "Average GDP Per Capita"
128
+ )
129
+ })
130
+
131
+ output$Population <- renderValueBox({
132
+ req(query_chat$df())
133
+ valueBox(
134
+ value = round(mean(query_chat$df()$pop, na.rm = TRUE), 0),
135
+ color = "primary",
136
+ icon = icon("people-group"),
137
+ elevation = 4,
138
+ width = 4,
139
+ subtitle = " ",
140
+ footer = "Average Population"
141
+ )
142
+ })
143
+
144
+ output$LifeExp <- renderValueBox({
145
+ req(query_chat$df())
146
+ valueBox(
147
+ value = round(mean(query_chat$df()$lifeExp, na.rm = TRUE), 2),
148
+ color = "warning",
149
+ icon = icon("person-walking"),
150
+ elevation = 4,
151
+ width = 4,
152
+ subtitle = " ",
153
+ footer = "Average Life Expectancy"
154
+ )
155
+ })
156
+
157
+ # write logic for Gemini chat
158
+ gemini <- chat_google_gemini(
159
+ system_prompt = "You are a friendly and helpful economic and financial expert who only answers questions around country economy and finance. If a user asks a question that is not related to economics or finance, give the following polite response: 'I'm sorry, I can only provide economic and financial information'.
160
+ Also, if a user asks for specific or personal financial advice, give the following polite response: 'I'm sorry, I cannot provide specific financial advice. Please consult a financial advisor for personalized guidance.'",
161
+ model = "gemini-2.0-flash",
162
+ api_key = api_key,
163
+ echo = T
164
  )
165
+
166
+ observeEvent(input$gemini_chat_user_input, {
167
+
168
+ # input$gemini_chat_user_input is from the chat id in the UI
169
+ gemini$chat_async(input$gemini_chat_user_input)$then(function(response) {
170
+ chat_append("gemini_chat", response)
171
+ })$catch(function(error) {
172
+ warning("An error occurred during chat_async: ", error$message)
173
+ })
174
+ })
175
+
176
  }
177
 
178
+ # Run the application
179
+ shinyApp(ui = ui, server = server)