Ответ 1
Чтобы правильно группировать переменные для построения графика, geom_bar
требует, чтобы значения x
были числовыми, а значения fill
были факторами или что аргумент group
используется для явного указания группирующих переменных. Однако plotly
выдает ошибку, когда используется group
. Подход ниже преобразует переменные x
в переменные integer
и fill
в factor
, чтобы они были правильно сгруппированы. Это позволяет использовать geom_bar
для вычисления процентов.
Во-первых, однако, интересно, правильно ли указан mydata
. Учитывая, что данные представляют собой сочетание символа и целого числа, cbind(Location, Brand, Year, Q1, Q2)
дает матрицу символов, которая затем преобразуется в data.table
, где все переменные являются символьным. В приведенном ниже коде я определил mydata непосредственно как data.table
, но преобразовал Q1
в режим символов, так что mydata
содержит комбинацию символов и числовых.
Используемый ниже подход заключается в создании нового фрейма данных plotdata
, содержащего данные x
и fill
. Данные x
преобразуются в числовые, если необходимо, сначала делая его переменной-фактором, а затем используя unclass
для получения кодовых чисел фактора. Данные fill
преобразуются в коэффициент. Затем plotdata
генерирует график ggplot
, который затем отображается с помощью plotly
. Код содержит пару других модификаций для улучшения внешнего вида диаграммы.
ИЗМЕНИТЬ
Код ниже обновлен, чтобы отобразить имя переменной строки под ней. Также процент и количество для каждого бара отображаются только тогда, когда указатель мыши нависает над панелью.
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)