0

I'm new to R and R Shiny. I'm currently trying to create an R Shiny app to display a summary of linear (y~x), quadratic (y~x^2+x) and cubic (y~x^3x^2+x) regression results for annual sea level values over a selected period for a selected location. The period is determined by the user selecting a start year and end year from a range slider, while the location is selected by the user from a drop down box. I then want to generate a linear, quadratic and cubic regression model from the data selected by the user and display each regression summary results in separate tables.

So far I've managed to generate a filtered data table from the parameters selected by the user above with columns containing the linear, quadratic and cubic terms for the regression model. However when I try to generate the regression results using LinearModel <- lm(input$var ~ ., data = dt) which I've taken and modified from a answer to a similar question previously asked elsewhere on here, I get the error Error in as.data.frame.default(data, optional = TRUE) : cannot coerce class ‘"function"’ to a data.frame.

The data tables used for the linear, quadratic and cubic regression are each displayed separately in my code. This is for information and also as a placeholder to be replaced with the relevant regression results.

Finally, I would like the data displayed as integers, but when I when I try to convert the data in the data frame to integers using my_data[,-1] <-round(my_data[,-1],0) it still displays to two decimal places?

Much appreciated

Bryan.

library(shiny)

Year <- c(2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009)
Year2 <- Year^2
Year3 <- Year^3
Auckland <- c(1760, 1549, 1388, 1967, 1326, 1765, 1814, 1693, 1502, 1751)
Wellington <- c(2176, 3154, 1138, 1196, 2132, 3176, 4181, 5169, 3150, 4175)
Lyttelton <- c(2176, 3154, 1138, 1196, 2132, 3176, 4181, 5169, 3150, 4175)
my_data <- as.data.frame(cbind(Year,Year2,Year3, Auckland,Wellington, Lyttelton))
my_data[,-1] <-round(my_data[,-1],0) #Convert my_data to integers - doesn't work? 

ui <- fluidPage(
  titlePanel("New Zealand Annual Mean Sea Level (MSL) Regression Summary"),

  sidebarLayout(
    sidebarPanel(
      helpText("Annual Mean Sea Level Summary for various locations around NZ."),

      selectInput("var", 
                  label = "Choose a Location",
                  choices = c("Auckland",
                              "Lyttelton",
                              "Wellington"),
                  selected = "Auckland"),

      sliderInput("range", 
                  label = "Choose a start and end year:",
                  min = min(my_data$Year), max = max(my_data$Year), value = c(2003, 2008),sep = "",)
    ),
    mainPanel(
      tableOutput("LinearRegression"),
      tableOutput("QuadraticRegression"),
      tableOutput("CubicRegression")
    )
  )
)
server <- function(input, output) {

  output$LinearRegression <- renderTable({
    dt <- my_data[my_data$Year >= input$range[1] & my_data$Year <= input$range[2],]
    dt[,c(input$var,"Year")]
  },include.rownames=FALSE)
  #Below line doesn't work?
  #LinearModel <- lm(input$var ~ ., data = dt)

  output$QuadraticRegression <- renderTable({
    dt <- my_data[my_data$Year >= input$range[1] & my_data$Year <= input$range[2],]
    dt[,c(input$var,"Year","Year2")]
  },include.rownames=FALSE)
  #Below line doesn't work?
  #QuadraticModel <- lm(input$var ~ ., data = dt)

  output$CubicRegression <- renderTable({
    dt <- my_data[my_data$Year >= input$range[1] & my_data$Year <= input$range[2],]
    dt[,c(input$var,"Year","Year2","Year3")]
  },include.rownames=FALSE)
  #Below line doesn't work?
  #CubicModel <- lm(input$var ~ ., data = dt) 
}
shinyApp(ui, server)
Bryan Ward
  • 53
  • 1
  • 6

1 Answers1

1

You take the data for each model out of the various renderXXXX calls and make it a reactive. You can use is as the input for both the table renderers and the regression summary outputs. Also, the output from lm is not a table, so you can't user renderTable to render it. Finally, there was a problem inserting the value of input$var into your lm call.

So, I've changed your tableOutput("LinearRegression") to VerbatimTextOutput("LinearRegression"). Then , in the server...

  filteredData <- reactive({
    dt <- my_data[my_data$Year >= input$range[1] & my_data$Year <= input$range[2],]
    dt[,c(input$var,"Year")]
    dt
  })

  output$LinearRegression <- renderPrint({
    lm(formula(paste(input$var, "~ .")), data = filteredData())
  })

You can amend the other outputs in a similar fashion.

Incidentally, your data is not tidy. I strongly suggest you make it so. A little effort now will save you much pain in the future.

Limey
  • 10,234
  • 2
  • 12
  • 32
  • Thanks @ Limey. Apologies for the late response. I've made the changes you've suggested above and added `summary()` to each of the `output$renderprint` commands to get `output$renderprint <- renderPrint(summary({lm(formula(paste(input$var, "~ .")), data = filteredData()) }))` which gives me exactly what I want. Will take a look at the "tidy" link you provided to try and tidy my data. Much appreciated. – Bryan Ward Jun 14 '20 at 02:41