Reputation: 53
I'm new in RShiny however have a little experience in R. I have just started working on R shiny and trying to prepare a simple two quantity linechart versus week on X axis. As its more presentable, I've used a csv upload feature and dynamically selecting the value to be populated on the UI. The sample CSV data that I'm using is as follows:
year-week Group big small Time
1415 G1 10 5 1
1416 G1 20 6 2
1429 G1 15 4 3
1530 G1 17 5 4
1535 G1 20 7 5
1601 G1 13 6 6
1606 G1 12 5 7
1410 G2 9 3 1
1415 G2 11 4 2
1439 G2 13 5 3
1529 G2 15 6 4
1531 G2 15 4 5
1610 G2 12 5 6
1615 G2 19 6 7
1412 G3 9 10 1
1417 G3 20 6 2
1452 G3 13 5 3
1501 G3 10 4 4
1530 G3 17 7 5
1620 G3 16 5 6
My main objective is:
1) Select a CSV and upload it (It's working)
2)Take week on x axis (it's working with a small work around. Since I have year week and it's discrete value like 1415 which means 2014,15th week and then 1420 which means same year 20th week, then is 1515 that is for 2015, week 15th and so on. I wanted to plot it as is but on x axis, it's plotting a continuous week number. So, as a work around I just made a column for sequential weeks as time. Any hints on how to use the year week column as is and not as a continuous function on X axis is much appreciated.)
3) Select two dynamic axis and then plot them as line charts on Y axis with different colours (it's working)
4) Add label for the two lines added on Y. (It's not working. As the two plotted lines aren't a part of factor, but are two different columns getting selected dynamically, I'm unable to plot legend to explain which colour corresponds to which line. Require help on this).
5) Then the last part is that I want to include a dynamic filter for group number. (It's not working and need help on this) I tried putting selectinput drop down in UI but not sure how to map it to the selected CSV file in server.R .I can't directly put values since there are 100's of rows corresponding to one group and there are multiple groups. However, I know that only one column requires that filter and only that column's filter shall show the line charts but just little confused on how to enter that part. I've gone through many articles and questions but did not get a similar situation in which other fields are getting dynamically selected.
Following is the code and it's working for one group, taking week sequence as work around inspite of year-week, because year week is till 52 only and it treats gaps in between 1452 & 1501. So I require help on the legend part and the code to filter the groups so it can run on all the data together.
Following is the code I've worked till now:
UI.R
library(ggvis)
library(shiny)
shinyUI(pageWithSidebar(
div(),
sidebarPanel(
fileInput('datfile', ''),
selectInput('x', 'x:' ,'x'),
selectInput('y', 'y:', 'y'),
selectInput('z', 'z:', 'z'),
######### Need to choose one of the following 2 methods for filtering ########
#1#
#selectInput("w", label = h3("Filter group"),
# ("Group" = "Group"),selected = "Group"),
############################## OR ###################################
# 2# To make a select box
selectInput("select", label = h3("Filter Group"),
choices = list("G1" = 1, "G2" = 2, "G3" = 3),
selected = 1),
######################################################################
hr(),
fluidRow(column(3, verbatimTextOutput("value"))),
uiOutput("plot_ui")
),
mainPanel(
ggvisOutput("plot")
)
))
Server.R
library(shiny)
library(dplyr)
library(ggvis)
shinyServer(function(input, output, session) {
#load the data when the user inputs a file
theData <- reactive({
infile <- input$datfile
if(is.null(infile))
return(NULL)
d <- read.csv(infile$datapath, header = T)
d
})
# dynamic variable names
observe({
data<-theData()
updateSelectInput(session, 'x', choices = names(data))
updateSelectInput(session, 'y', choices = names(data))
updateSelectInput(session, 'z', choices = names(data))
}) # end observe
#gets the y variable name, will be used to change the plot legends
yVarName<-reactive({
input$y
})
#gets the x variable name, will be used to change the plot legends
xVarName<-reactive({
input$x
})
#gets the z variable name, will be used to change the plot legends
zVarName<-reactive({
input$z
})
#make the filteredData frame
filteredData<-reactive({
data<-isolate(theData())
#if there is no input, make a dummy dataframe
if(input$x=="x" && input$y=="y" && input$z=="z"){
if(is.null(data)){
data<-data.frame(x=0,y=0,z=0)
}
}else{
data<-data[,c(input$x,input$y,input$z)] # Here data shall be filtered
names(data)<-c("x","y","z")
}
data
})
#plot the ggvis plot in a reactive block so that it changes with filteredData
vis<-reactive({
plotData<-filteredData()
plotData %>%
ggvis(~x, ~y) %>%
#ggvis(~x, ~y, storke = c(~y,~z)) %>% # It's not working & not picking y&z together
#set_options(duration=0) %>%
layer_paths(stroke := "darkblue", fill := NA) %>%
layer_paths(x = ~x, y = ~z, stroke := "orangered", fill := NA) %>%
add_axis("y", title = "Big v/s small") %>%
add_axis("x", title = xVarName()) %>%
#add_legend('stroke', orient="left") %>% # Unable to put the legend
add_tooltip(function(df) format(sqrt(df$x),digits=2))
})
vis%>%bind_shiny("plot", "plot_ui")
})
Any help is much appreciated. It may not be that tough and I've done a similar part in R by using dplyr for subset and filter but not sure how to map the same here. If anything above is unclear or require more info, please let me know. If the solution is better by loading the CVS directly or using plot inspite of ggvis, then also I'm ok to change the code piece but want to meet my objective.
Upvotes: 0
Views: 408
Reputation: 53
UI.R
library(ggvis)
library(shiny)
shinyUI( fluidPage ( (img(src="picture.jpg")),
theme = "bootstrap.css",
fluidRow(
#headerPanel(title=div(img(src="picture.jpg"))),
column(9, align="center", offset = 2,
textInput("string", label="",value = "Big V/s Small"),
tags$style(type="text/css", "#string { height: 50px; width: 100%; text-align:center; font-size: 26px;}")
)
),
pageWithSidebar(
div(),
sidebarPanel(
fileInput('datfile', ''),
selectInput('x', 'x:' ,'x'),
selectInput('y', 'y:', 'y'),
selectInput('z', 'z:', 'z'),
################ Need to choose one of the following method for filtering ############
# To make a select box
selectInput("w", label = h3("Filter Group"),
choices = list()),
######################################################################
hr(),
fluidRow(column(3, verbatimTextOutput("value"))),
uiOutput("plot_ui")
),
mainPanel(
ggvisOutput("plot")
)
))
)
Sevrer.R
#install.packages('rsconnect')
#install.packages('bitops')
library(shiny)
library(dplyr)
library(ggvis)
library(reshape2)
shinyServer(function(input, output, session) {
#load the data when the user inputs a file
theData <- reactive({
infile <- input$datfile
if (is.null(infile))
return(NULL)
d <-
read.csv(infile$datapath,
header = T,
stringsAsFactors = FALSE)
d
})
# dynamic variable names
observe({
data <- theData()
updateSelectInput(session, 'x', choices = names(data))
updateSelectInput(session, 'y', choices = names(data))
updateSelectInput(session, 'z', choices = names(data))
updateSelectInput(session, 'w', choices = unique(data$group))
}) # end observe
#gets the y variable name, will be used to change the plot legends
yVarName <- reactive({
input$y
})
#gets the x variable name, will be used to change the plot legends
xVarName <- reactive({
input$x
})
#gets the z variable name, will be used to change the plot legends
zVarName <- reactive({
input$z
})
#gets the w variable name, will be used to change the plot legends
wVarName <- reactive({
input$w
})
#make the filteredData frame
filteredData <- reactive({
data <- isolate(theData())
#if there is no input, make a dummy dataframe
if (input$x == "x" && input$y == "y" && input$z == "z") {
if (is.null(data)) {
data <- data.frame(x = 0, y = 0, z = 0)
}
} else{
data = data[which(data$fineline_nbr == input$w), ]
data <- data[, c(input$x, input$y, input$z)]
names(data) <- c('x', input$y, input$z)
}
data
})
#plot the ggvis plot in a reactive block so that it changes with filteredData
vis <- reactive({
plotData <- filteredData()
plotData <- melt(plotData, id.vars = c('x'))
print(names(plotData))
plotData %>% ggvis(x = ~ x,
y = ~ value,
stroke = ~ variable) %>% layer_lines()
})
vis %>% bind_shiny("plot", "plot_ui")
})
Upvotes: 1