Tomas Alonso Rehor
Tomas Alonso Rehor

Reputation: 265

Shiny Table based on geom_smooth fit

I really need your help with this. Im trying to build a shiny app that can issue the approximate hours for projects depending on size of previous completed projects.(see df below)

Df looks like this (sample).

    Department Hours   SIZE
1         HVAC  1281  38000
7         HVAC   202  38000
13        HVAC    52  33000
19        HVAC   118  33000
25        HVAC  2069  22000
31        HVAC  1546  22000
37        HVAC   282    450
43        HVAC     1  17000
49        HVAC   725   7000
55        HVAC    50 250000
61        HVAC  1573  11000
67        HVAC   100  11000
73        HVAC   562    500
79        HVAC  1441   7900

I make ggplot plots with geom_smooth to see the average hour requirement for each department based on the SIZE.

This is how the look like.

enter image description here

And this is the Shiny APP skeleton that im working on. I want the table to change the value according to the ggplot blue line. So for example if you set the SIZE input to 50.000 in this example the table would show a value of around 2000.

I really hope it makes sense as is I know is confusing.

enter image description here

Any ideas on how to proceed? I would really appreciate.

Here is the Shiny APP code

library(shiny)
hello <- data.frame(125)
colnames(hello) <- "VALUE"

ui <- fluidPage(titlePanel("Pricing Calculator", windowTitle = "app"),

                sidebarLayout(sidebarPanel(


                  sliderInput(inputId = "slideruno",label = "Size (m2)", min = 0, max = 250000,
                              value = 50000,step = 2500, ticks = T)

                )

                ,mainPanel(
                  tableOutput(outputId = "tableuno")
                )
                ))


server <- function(input, output) {

  output$tableuno <- renderTable(hello)  

}

shinyApp(ui, server) 

And the code used for making the ggplot:

  ggplot(HVAC, aes(SIZE, Hours)) + geom_point(aes(color = Department)) + stat_smooth()

Data debut

dput(hvac)

structure(list(Department = c("HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC", 
"HVAC", "HVAC", "HVAC", "HVAC", "HVAC", "HVAC"), Hours = c(1281, 
202, 52, 118, 2069, 1546, 282, 1, 725, 50, 1573, 100, 562, 1441, 
475, 1415, 191, 1498, 33, 763, 1, 81, 1433, 305, 1561, 1960, 
6834, 274, 1465, 646, 3586, 77, 52, 395, 197, 10, 67, 33, 59, 
431, 4, 154, 665, 461, 35, 331, 401, 605, 26, 99, 3981, 598, 
47, 434, 39, 3578, 364, 124, 666, 58, 3086, 375, 7, 277, 29, 
47), SIZE = c(38000, 38000, 33000, 33000, 22000, 22000, 450, 
17000, 7000, 250000, 11000, 11000, 500, 7900, 7900, 7900, 77000, 
1e+05, 1000, 2250, 2250, 15000, 35000, 7000, 7000, 1000, 51000, 
51000, 15000, 29000, 23000, 23000, 23000, 3600, 27500, 2800, 
2800, 3500, 3500, 6500, 20000, 192000, 2200, 8000, 30000, 36000, 
6500, 6500, 11000, 70000, 55000, 3000, 1600, 36000, 36000, 17000, 
1800, 5800, 15000, 46000, 26000, 34000, 7500, 130000, 36000, 
15000)), .Names = c("Department", "Hours", "SIZE"), class = "data.frame", row.names = c(1L, 
7L, 13L, 19L, 25L, 31L, 37L, 43L, 49L, 55L, 61L, 67L, 73L, 79L, 
85L, 91L, 103L, 109L, 115L, 121L, 127L, 133L, 139L, 145L, 151L, 
157L, 163L, 169L, 175L, 181L, 187L, 193L, 199L, 205L, 211L, 217L, 
223L, 229L, 241L, 253L, 259L, 265L, 271L, 277L, 283L, 289L, 295L, 
301L, 307L, 313L, 319L, 325L, 331L, 337L, 343L, 349L, 355L, 361L, 
367L, 373L, 379L, 397L, 403L, 415L, 421L, 445L))

Upvotes: 0

Views: 519

Answers (2)

Batanichek
Batanichek

Reputation: 7871

Or you can get stat_smooth from ggplot like

p=ggplot(HVAC, aes(SIZE, Hours)) + geom_point(aes(color = Department)) + stat_smooth(aes(outfit=fit<<-..y..))
    ddd=ggplot_build(p)$data[[2]][,1:2]

and full shiny will be

library(shiny)
library(ggplot2)

ui <- fluidPage(titlePanel("Pricing Calculator", windowTitle = "app"),

                sidebarLayout(sidebarPanel(


                  sliderInput(inputId = "slideruno",label = "Size (m2)", min = 0, max = 250000,
                              value = 50000,step = 2500, ticks = T)

                )

                ,mainPanel(
                  tableOutput(outputId = "tableuno")
                )
                ))



server <- function(input, output) {

  output$tableuno <- renderTable({
    p=ggplot(HVAC, aes(SIZE, Hours)) + geom_point(aes(color = Department)) + stat_smooth(aes(outfit=fit<<-..y..))
    ddd=ggplot_build(p)$data[[2]][,1:2]
    ddd=ddd[ddd[[2]]<=input$slideruno,]

    data.frame("Value"=ddd[nrow(ddd),1])


  })  

}

shinyApp(ui, server) 

Of course if I right understand how you want to get one value from stat_smooth()

Upvotes: 1

Vincent Bonhomme
Vincent Bonhomme

Reputation: 7453

Not sure to fully understand but you probably need to build a model in your server side, then use predict. stat_smooth uses a loess by default. An example on the iris dataset` as I can't reproduce your example:

mod <- loess(Sepal.Length ~ Sepal.Width, iris)
predict(mod, newdata = data.frame(Sepal.Width=3))

Server side: Here you probably just have to change it with your values (Hours, SIZE, HVAC) and change 3 for input$slideruno. Then assign the result of predict to output$predicted within a renderText.

UI side: just textOutput("predicted").

Upvotes: 0

Related Questions