I want to use the nPlot() function in RCharts to plot percentages of people falling into discrete groups, rather than frequencies.
For example: Using the HairEyeColor data/code below I am able to consider the percentage of people with different hair colors (my grouping variable), as a function of their eye color.
## server.r
library(rCharts)
library(shiny)
library(reshape)
HairEyeColor1 <- melt(round(prop.table(HairEyeColor[,,1],2)*100,2))
names(HairEyeColor1) <- c("Hair", "Eye", "Percent")
shinyServer(function(input, output) {
output$myChart <- renderChart({
p1 <- nPlot(Percent ~ Eye, group = "Hair", data = HairEyeColor1, type = multiBarChart")
p1$addParams(dom = 'myChart')
return(p1)
})
})
## ui.R
library(rCharts)
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using NVD3.js"),
sidebarPanel(
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
)
),
mainPanel(
div(class='wrapper',
tags$style(".Nvd3{ height: 400px;}"),
showOutput("myChart","Nvd3")
)
)
))
Say I just wanted to look at a single factor, like Hair. Is there a way to plot their percentages using nPlot()?
prop.table(rowSums(HairEyeColor[,,1]))
Black Brown Red Blond
0.2007168 0.5125448 0.1218638 0.1648746
With type=multiBarChart I have tried:
p1 <- nPlot(Percent ~ , group = "Hair", data = HairEyeColor1, type = multiBarChart")
This fails entirely. I have also tried:
p1 <- nPlot(Percent ~ 1, group = "Hair", data = HairEyeColor1, type = multiBarChart")
This at least passes some graph to Shiny UI. But this looks hideous and functionality (appearance of X/Y-axis, clicking on graph) is all lost.
I thought this would be appropriate for nPlot(type=discreteBarChart) but the data layout for this seems to want a dataframe with a single factor variable. So I can't quite see how to trick nPlot(type=discreteBarChart) into taking a vector of proportions/percentages.
Any suggestions appreciated.
Here is how to do it with nPlot. You can see the resulting plot here. If you want to stack the bars by default, add the line n1$chart(stacked = TRUE) before you print the chart.
# prepare data
require(plyr)
dat = as.data.frame(HairEyeColor)
dat = ddply(dat, .(Hair), summarize, Freq = sum(Freq), Group = "A")
# draw chart
require(rCharts)
n1 <- nPlot(Freq ~ Group, data = dat, group = 'Hair', type = 'multiBarChart')
n1
Related
I am trying to build my first shiny app and have come across an error I can't resolve. I have searched and searched but can't seem to find an answer that resolves this question.
My code is below using the mtcars dataset. The goal is to develop visual and text analysis tools for a survey dataset. I currently have two drop down menus with survey questions, a drop down menu with a grouping variable menu, and some radio buttons for plot types. I am trying to create the first plot - a histogram. After I run the code I get the correctly rendered data tables, but no histogram plot - and the error:
object 's1' not found
I have tried this with and without wrapping my ggplot code with print().
Any help would be very appreciated !
Thanks!
library(shiny)
install.packages("shinythemes")
library(shinythemes)
library(ggplot2)
library(dplyr)
mt <- mtcars
ui <- fluidPage(theme=shinytheme("readable"),
titlePanel("Test"),
sidebarLayout(
sidebarPanel(
# use mpg and cyl as survey option groups
selectizeInput(inputId = 's1',
label = 'Survey Question 1 (X-Axis)',
choices = c("mpg", "cyl")),
selectizeInput(inputId = 's2',
label ='Survey Question 2 (Y-Axis)',
choices = c("mpg", "cyl")),
# use gear and vs as grouping variables
selectizeInput(inputId = 'g',
label = 'Group By',
choices = c("Gear"="gear", "VS" = "vs")),
# use radio buttons for pot type options
radioButtons(inputId = 'plottype',
label = 'Plot Type',
choices = c("Histogram" = "geom_histogram", "Box Plot" = "geom_boxplot", "Scatterplot" = "geom_point")
)
),
mainPanel(
plotOutput("plot1"), # ui for plot
verbatimTextOutput("table1") # ui for table
)
)
)
server <- function(input, output, session) {
## subset dataset to include only two options for now - include grouping after
plotData <- reactive({
((mt[,c(input$s1,input$s2)])) ## data for plot
})
## render hist plot in ggplot
output$plot1 <- renderPlot({
d1<-(plotData())
print(ggplot(d1, aes(x=s1)) + geom_histogram(fill = "dark green", alpha = 0.6, binwidth = 1))
print(str(d1))
})
## render summary table for survey questions
output$table1 <- renderPrint({
summary(plotData())
})
}
shinyApp(ui = ui, server = server)
## but this works
ggplot(mt, aes(x=mpg)) + geom_histogram(fill = "dark green", alpha = 0.6, binwidth = 1)
There's no column s1 in the data set d1. Use ggplot(d1, aes_string(x=input$s1)).
I am learning Shiny and wanted help on a app that I am creating. I am creating an app that will take dynamic inputs from the user and should generate bar and line charts. I managed to create the bar chart but it is generating incorrect result.
What I am looking for is variable selected in row should be my x-axis and y-axis should be percentage. scale to be 100%. column variable should be the variable for comparison and for that I am using position = "dodge". My data is big and I have created a sample data to depict the situation. Since actual data is in data.table format I am storing the sample data as data.table. Since I am not sure how I can include this data which is not in a file format, I create it first so that it is in R environment and then run the app -
Location <- sample(1:5,100,replace = T)
Brand <- sample(1:3,100,replace = T)
Year <- rep(c("Year 2014","Year 2015"),50)
Q1 <- sample(1:5,100,replace = T)
Q2 <- sample(1:5,100,replace = T)
mydata <- as.data.table(cbind(Location,Brand,Year,Q1,Q2))
Below is the Shiny code that I am using -
library("shiny")
library("ggplot2")
library("scales")
library("data.table")
library("plotly")
ui <- shinyUI(fluidPage(
sidebarPanel(
fluidRow(
column(10,
div(style = "font-size: 13px;", selectInput("rowvar", label = "Select Row Variable", ''))
),
tags$br(),
tags$br(),
column(10,
div(style = "font-size: 13px;", selectInput("columnvar", "Select Column Variable", ''))
))
),
tabPanel("First Page"),
mainPanel(tabsetPanel(id='charts',
tabPanel("charts",tags$b(tags$br("Graphical Output" )),tags$br(),plotlyOutput("plot1"))
)
)
))
server <- shinyServer(function(input, output,session){
updateTabsetPanel(session = session
,inputId = 'myTabs')
observe({
updateSelectInput(session, "rowvar", choices = (as.character(colnames(mydata))),selected = "mpg")
})
observe({
updateSelectInput(session, "columnvar", choices = (as.character(colnames(mydata))),selected = "cyl")
})
output$plot1 <- renderPlotly({
validate(need(input$rowvar,''),
need(input$columnvar,''))
ggplot(mydata, aes(x= get(input$rowvar))) +
geom_bar(aes(y = ..prop.., fill = get(input$columnvar)), position = "dodge", stat="count") +
geom_text(aes( label = scales::percent(..prop..),
y= ..prop.. ), stat= "count", vjust = -.5) +
labs(y = "Percent", fill=input$rowvar) +
scale_y_continuous(labels=percent,limits = c(0,1))
})
})
shinyApp(ui = ui, server = server)
If you see the problem is -
All bars are 100%. Proportions are not getting calculated properly. Not sure where I am going wrong.
If I try to use the group parameter it gives me error saying "input" variable not found. I tried giving group as group = get(input$columnvar)
I believe I need to restructure my data for line chart. Can you help with how I can dynamically restructure the data.table and then re-use for the line chart. How can I generate the same bar chart as a line chart.
I am using renderplotly so that I use the features of plotly to have the percentages displayed with the mouse movement / zoom etc. However I can see input$variable on mouse movement. How can I get rid of it and have proper names.
Have tried to detail out the situation. Do suggest some solution.
Thank you!!
To properly group variables for plotting, geom_bar requires that the x values be numeric and the fill values be factors or that the argument group be used to explicitly specify grouping variables. However, plotly throws an error when group is used. The approach below converts x variables to integer and fill variables to factor so that they are properly grouped. This retains the use of geom_bar to calculate the percentages.
First, however, I wonder if mydata is specified correctly. Given that the data is a mix of character and integer, cbind(Location, Brand, Year, Q1, Q2) gives a character matrix which is then converted to a data.table where all variables are character mode. In the code below, I've defined mydata directly as a data.table but have converted Q1 to character mode so that mydata contains a mix of character and numeric.
The approach used below is to create a new data frame, plotdata, containing the x and fill data. The x data is converted to numeric, if necessary, by first making it a factor variable and then using unclass to get the factor integer codes. The fill data converted to a factor. plotdata is then used generate the ggplot plot which is then displayed using plotly. The code includes a couple of other modifications to improve the appearance of the chart.
EDIT
The code below has been updated to show the name of the row variable beneath it's bar. Also the percentage and count for each bar are only shown when the mouse pointer hovers above the bar.
library("shiny")
library("ggplot2")
library("scales")
library(plotly)
library(data.table)
Location <- sample(1:5,100,replace = T)
Brand <- sample(1:3,100,replace = T)
Year <- rep(c("Year 2014","Year 2015"),50)
Q1 <- sample(1:5,100,replace = T)
Q2 <- sample(1:5,100,replace = T)
Q3 <- sample(seq(1,3,.5), 100, replace=T)
mydata <- data.table(Location,Brand,Year,Q1,Q2, Q3)
#
# convert Q1 to character for demonstation purposes
#
mydata$Q1 <- as.character(mydata$Q1)
ui <- shinyUI(fluidPage(
sidebarPanel(
fluidRow(
column(10,
div(style = "font-size: 13px;", selectInput("rowvar", label = "Select Row Variable",
choices=colnames(mydata)))),
tags$br(),
tags$br(),
column(10,
div(style = "font-size: 13px;", selectInput("columnvar", label="Select Column Variable",
choices=colnames(mydata))))
)
),
tabPanel("First Page"),
mainPanel(tabsetPanel(id='charts',
tabPanel("charts",tags$b(tags$br("Graphical Output" )),tags$br(),plotlyOutput("plot1"))
)
)
))
server <- shinyServer(function(input, output,session){
updateTabsetPanel(session = session
,inputId = 'myTabs')
observe({
updateSelectInput(session, "rowvar", choices = colnames(mydata), selected=colnames(mydata)[1])
})
observe({
updateSelectInput(session, "columnvar", choices = colnames(mydata), selected=colnames(mydata)[2])
})
output$plot1 <- renderPlotly({
#
# create data frame for plotting containing x variables as integer and fill variables as factors
#
if(is.numeric(get(input$rowvar))) {
rowvar_brks <- sort(unique(get(input$rowvar)))
rowvar_lbls <- as.character(rowvar_brks)
plotdata <- data.frame(get(input$rowvar), factor(get(input$columnvar)) )
}
else {
rowvar_factors <- factor(get(input$rowvar))
rowvar_brks <- 1:nlevels(rowvar_factors)
rowvar_lbls <- levels(rowvar_factors)
plotdata <- data.frame(unclass(rowvar_factors), factor(get(input$columnvar)) )
}
colnames(plotdata) <- c(input$rowvar, input$columnvar)
validate(need(input$rowvar,''),
need(input$columnvar,''))
col_width <- .85*mean(diff(rowvar_brks))
sp <- ggplot(plotdata, aes_(x = as.name(input$rowvar), fill = as.name(input$columnvar))) +
geom_bar( aes(y= ..prop..), stat="count", position=position_dodge(width=col_width)) +
geom_text(aes( label = paste(scales::percent(..prop..),"<br>", "count:",..count..,"<br>"), y= ..prop.. + .01),
stat= "count", position=position_dodge(width=col_width), size=3, alpha=0) +
labs(x= input$rowvar, y = "Percent", fill=input$columnvar) +
scale_y_continuous(labels=percent) +
scale_x_continuous(breaks=rowvar_brks, labels=rowvar_lbls)
ggplotly(sp, tooltip="none")
})
})
shinyApp(ui = ui, server = server)
I have a app, where I want to use rCharts and polycharts, to create a plot with a tooltip. But the plot doesn't show up, when I load the shiny app, and I can't figure out why.
Here is my ui.R:
library(shiny)
require(rCharts)
shinyUI(fluidPage(
titlePanel("Please work..."),
sidebarLayout(
sidebarPanel( "Test:",
uiOutput("TestSelection")),
mainPanel("Plots (show me the money, please!):",
showOutput("tempplot","polycharts")
)
)
))
And here's my server.R:
library(shiny)
require(rCharts)
#Test of rcharts and shiny.
df1 <- read.csv("//KED-FILE/ASIC-Shared/users/jhertel/Work/R_workspace/oban_test_data.csv",quote="")
shinyServer(function(input, output, session){
output$TestSelection <- renderUI({
df <- df1
selectInput("TestSel", "Test Variable", ls(df, pattern = ".*?_meas|.*?_calc"))
})
output$tempplot <- renderChart2({
dataPlot <- df1[,c("DUT", input$TestSel, "Temperature")]
r1 <- rPlot(input$TestSel ~ Temperature,
data = dataPlot,
type = "point",
tooltip = "#!function(item){return item.DUT}!#",
sample = FALSE)
r1$guides(
x = list(
min = pretty( dataPlot$Temperature ) [1],
max = tail( pretty( dataPlot$Temperature ), 1 ),
numticks = length( pretty( dataPlot$Temperature ) ),
labels = pretty( dataPlot$Temperature )
),
y = list(
min = pretty( dataPlot[, input$TestSel] ) [1],
max = tail( pretty( dataPlot[, input$TestSel] ), 1 )
)
)
return(r1)
})
})
I've tried different things, such as options(RCHART_LIB = 'polycharts'), using as.formula around input$TestSel ~ Temperature, adding a reactive element on the TestSelection-ui, I've tried changing browser, from internal, to Firefox, to Chrome.
I am suspecting the input$TestSel ~ Temperature to be the reason, as when I inspect the javascript with Chrome, it doesn't look like input$TestSel has been interpreted to the desired value. But I am a total noob to javascript, so I wouldn't know. EDIT: I am fairly certain that my error occurs here, as setting the changing input$TestSel to a desired value results in the desired plot... Still don't know how to solve it, though.
When just using R the plot shows up as desired in the viewer.
I am trying to embed an RChart into a shiny app. Specifically, working with the function nPlot and the type=lineChart NVD3 feature. I am trying to plot 3 density curves for simulated Normal data. I am trying to achieve some of the functionality described in the example below:
http://nvd3.org/ghpages/line.html
My issues:
How to have different colours for different density curves?
How to have the feature to click on group variable (1), (2), (3) to effectively remove the selected density. Similar to clicking on "Sine Wave" (top right) in the example to remove the orange sine curve?
How to add x-axis and y-axis labels? My $params$xAxis= call does not work.
Below are my server.R and ui.R files:
## server.r
library(rCharts)
library(shiny)
x <-rnorm(1000,0,1)
y <-rnorm(1000,1,1)
z <-rnorm(1000,2,1)
out <- c(x,y,z)
grp <- c(rep(0,1000),rep(1,1000),rep(2,1000))
data <- as.data.frame(cbind(out,grp))
dens <- by(data$out, data$grp, density)
d <- unlist(c(dens[[1]][1][1], dens[[2]][1][1], dens[[3]][1][1]))
support <- unlist(c(dens[[1]][2][1], dens[[2]][2][1], dens[[3]][2][1]))
grpvar <- c(rep(0,length(unlist(dens[[1]][1][1]))), rep(1,length(unlist(dens[[2]][1][1]))), rep(2,length(unlist(dens[[3]][1][1]))))
dat <- as.data.frame(cbind(d,support,grpvar))
shinyServer(function(input, output) {
output$myChart <- renderChart({
p1 <- nPlot(support~d, group=grpvar, data = dat, type = "lineChart")
p1$addParams(dom = 'myChart')
p1$params$width = 600
p1$params$height = 400
p1$params$xAxis = "Support"
p1$params$yAxis = "Density"
p1$chart(tooltipContent = "#! function(key, x, y, e){
return '<b>Group</b>: ' + e.point.grpvar
} !#")
return(p1)
})
})
## ui.R
library(rCharts)
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using NVD3.js"),
sidebarPanel(
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
)
),
mainPanel(
div(class='wrapper',
tags$style(".Nvd3{ height: 600px;}"),
showOutput("myChart","Nvd3")
)
)
))
Thanks in advance for any help/advice you can provide.
You will just need to add quotes around grpvar, so
p1 <- nPlot(support~d, group="grpvar", data = dat, type = "lineChart")
I'm trying to embed an RChart into a shiny app. I'm specifically using the nPlot function to create a type=scatterChart NVD3 style plot. In the NVD3 website example below, there are two pieces of functionality I am interested in getting to work in my RCharts shiny app:
http://nvd3.org/ghpages/scatter.html
It appears that a "rug" is included along the x-axis and y-axis of the above example, demonstrating marginally where the x and y points occur most frequently along their respective supports.
Further, when one clicks on the chart and hovers over a specific point a vertical and horizontal line appear noting the (x,y) location of the corresponding point.
Does anyone know how to expand my code below to achieve these two pieces of functionality. Shiny server.r and ui.r scripts are included below.
## server.r
library(rCharts)
library(shiny)
x <- rnorm(100)
y <- rnorm(100)
dat <- as.data.frame(cbind(x,y))
shinyServer(function(input, output) {
output$myChart <- renderChart({
p1 <- nPlot(y ~ x, data = dat, type = "scatterChart")
p1$addParams(dom = 'myChart')
p1$params$height=400
p1$params$width=650
return(p1)
})
})
## ui.R
library(rCharts)
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("rCharts: Interactive Charts from R using NVD3.js"),
sidebarPanel(
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
),
wellPanel(
helpText( "Look at the pretty graph"
)
)
),
mainPanel(
div(class='wrapper',
tags$style(".Nvd3{ height: 400px;}"),
showOutput("myChart","Nvd3")
)
)
))
Thanks in advance for any advice you can provide.
This can be achieved using the following code:
p1$chart(
showDistX = TRUE,
showDistY = TRUE
)
return(p1)
Also, just as a note, while direct manipulation of p1$params works, it might be safer to specify height and width in this way:
p1 <- nPlot(
y ~ x,
data = dat,
type = "scatterChart",
height = 400,
width = 650
)