Reputation: 355
I'm designing an R program to output different graphs of any csv file input. I am using Rstudio Shiny and ggPlot2 (and maybe later D3!) to develop the program. Being new to these languages, however, I'm encountering some major problems. Here is my program so far:
Related post from me 2 days ago: How to Specify Columns when a user chooses a file to upload in R?
server.R
library(shiny)
library(datasets)
library(ggplot2)
X <- read.csv(file.choose())
# Define server logic required to summarize and view the selected dataset
shinyServer(function(input, output) {
# Generate a summary of the dataset
output$summary <- renderPrint({
dataset <- X
summary(dataset)
})
# Show the first "n" observations
output$view <- renderTable({
head(X, n = input$obs)
})
createPlot <- function(df, colx, coly) {
ggplot(data=df, aes(x=df[,colx],y=df[,coly]), environment = environment()) + geom_point(size = 3) + geom_line()
}
Y <- reactive({
X
})
# create a basic plot
output$plotBasic <- reactivePlot(function() {
df <- Y()
print(createPlot(df, colx=input$xa, coly=input$ya))
})
})
ui.R
library(shiny)
# Define UI for dataset viewer application
shinyUI(pageWithSidebar(
# Application title
headerPanel("My app!"),
# Sidebar with controls to select a dataset and specify the number
# of observations to view
sidebarPanel(
numericInput("obs", "Number of observations to view:", 13),
numericInput("xa", "Column to plot as X-axis:", 1),
numericInput("ya", "Column to plot as Y-axis:", 2)
),
# Show a summary of the dataset and an HTML table with the requested
# number of observations
mainPanel(
tabsetPanel(
tabPanel("Table", tableOutput("view")),
tabPanel("BasicGraph", plotOutput("plotBasic"))
)
)
))
I have a few problems with my program. I do not know how to display the column names in the csv data that was read on the graph (the uploaded file can be anything). Also, whenever I try to change the graph display (geom in ggplot function), it doesn't change the graph. Here I added "geom_line()" but it only displays the dots. If I try to do stat_smooth() it doesn't display the smoothing as well.
The other problem is that the graph is not displaying the data in order (for example, in the dataset I passed in, the months are in order , June, July, August, but in the graph they are jumbled).
Thanks for the help guys.
I've attached a picture of what the program looks like in case you can't run it.
https://i.sstatic.net/ut21l.png
Upvotes: 1
Views: 433
Reputation: 22496
There are multiple questions that need to be addressed.
Q1: I do not know how to display the column names in the csv data that was read on the graph (the uploaded file can be anything).
You would do that by making the UI "Dynamic." http://rstudio.github.io/shiny/tutorial/#dynamic-ui
In UI.R Add
uiOutput("opt.x"), #dynamic UI
uiOutput("opt.y") #value comes from Server.R
In Server.R Add
output$opt.x <- renderUI({
selectInput("xcolumn", "X column to Plot",
names(Y())
)
})
output$opt.y <- renderUI({
selectInput("ycolumn", "Y Column",
names(Y()))
})
Q2: Also, whenever I try to change the graph display (geom in ggplot function), it doesn't change the graph. Here I added "geom_line()" but it only displays the dots.
Most likely, there you should be getting a warning message from ggplot
re. grouping.
You can address that by explicitly specifying the group
parameter.
p <- p + geom_line(aes(group=colx))
Q3: The other problem is that the graph is not displaying the data in order (for example, in the dataset I passed in, the months are in order , June, July, August, but in the graph they are jumbled).
Ggplot is doing an internal ordering of dates. There are several questions on SO that address different ways to reorder. (ggplot2: sorting a plot)
Overall Here's a working version of my UI.R and Server.R
library(shiny)
library(datasets)
library(ggplot2)
X <- read.csv(file.choose())
# Define server logic required to summarize and view the selected dataset
shinyServer(function(input, output) {
output$opt.x <- renderUI({
selectInput("xcolumn", "X column to Plot",
names(Y())
)
})
output$opt.y <- renderUI({
selectInput("ycolumn", "Y Column",
names(Y()))
})
# Generate a summary of the dataset
output$summary <- renderPrint({
dataset <- X
summary(dataset)
})
# Show the first "n" observations
output$view <- renderTable({
head(X, n = input$obs)
})
createPlot <- function(df, colx, coly) {
p <- ggplot(data=df, aes(x=df[,colx],y=df[,coly]), environment = environment()) #+ geom_line(aes(x=df[,colx],y=df[,coly], group=colx))
p <- p + geom_line(aes(group=colx))
p <- p + xlab(names(df)[colx]) + ylab(names(df)[coly])
}
Y <- reactive({
X
})
# create a basic plot
output$plotBasic <- reactivePlot(function() {
df <- Y()
print(createPlot(df, colx=input$xcolumn, coly=input$ycolumn))
})
})
library(shiny)
# Define UI for dataset viewer application
shinyUI(pageWithSidebar(
# Application title
headerPanel("My app!"),
# Sidebar with controls to select a dataset and specify the number
# of observations to view
sidebarPanel(
numericInput("obs", "Number of observations to view:", 13),
uiOutput("opt.x"), #dynamic UI
uiOutput("opt.y") #value comes from Server.R
),
# Show a summary of the dataset and an HTML table with the requested
# number of observations
mainPanel(
tabsetPanel(
tabPanel("Table", tableOutput("view")),
tabPanel("BasicGraph", plotOutput("plotBasic"))
)
)
))
Hope that helps.
Upvotes: 2