Skip to content

Instantly share code, notes, and snippets.

@schaunwheeler
Last active October 13, 2015 14:07
Show Gist options
  • Save schaunwheeler/4207354 to your computer and use it in GitHub Desktop.
Save schaunwheeler/4207354 to your computer and use it in GitHub Desktop.
Shiny code for SegmentViewer Simulation
# The MIT License (MIT)
#
# Copyright (c) 2012 Schaun Jacob Wheeler
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
library(shiny)
library(plyr)
library(scales)
library(ggplot2)
library(reshape2)
set.seed(12435)
state <- sample(c("CA", "WA", "OR", "AZ", "NV", "UT"), 40000, replace = T)
lowgrade <- sample(c(0,1), 40000, replace = T)
lowgrade[sample(40000, 10000)] <- sample(c(5,7), 10000, replace = T)
lowgrade[sample(40000, 7000)] <- 9
highgrade <- sample(5:6, 40000, replace = T)
highgrade[lowgrade == 5] <- sample(c(8,12), sum(lowgrade == 5), replace = T)
highgrade[lowgrade == 7] <- 9
highgrade[lowgrade == 9] <- 12
income <- sample(1:10, 40000, replace = T) * 10000
revenue <- c(rnorm(20000, mean = 2000, sd = 2000),
rnorm(10000, mean = 2000, sd = 1000),
rnorm(10000, mean = 2000, sd = 4000))
revenue[revenue < 0] <- 0
insert_zeros <- sample(1:sum(revenue != 0),sum(revenue != 0)/1.2)
revenue[insert_zeros] <- 0
revenue <- sample(revenue, 40000)
schools <- data.frame(state,
lowgrade,
highgrade,
income,
revenue,
stringsAsFactors = F)
sch_tab <- ddply(schools,
.variables = c("state", "lowgrade", "highgrade", "income"),
function(df){
c("n" = nrow(df),
"sum" = sum(df$revenue),
"mean" = mean(df$revenue))
})
reg_line <- predict(lm(sum~mean, data = sch_tab),
newdata = data.frame("mean" = sch_tab$mean))
sch_tab$segment <- rep("More Profitable\nMore Difficult", nrow(sch_tab))
sch_tab$segment2 <- rep("Less Profitable\nMore Difficult", nrow(sch_tab))
sch_tab$segment[sch_tab$sum <= reg_line &
sch_tab$mean < median(sch_tab$mean)] <- "Less Profitable\nMore Difficult"
sch_tab$segment[sch_tab$sum > reg_line &
sch_tab$mean >= median(sch_tab$mean)] <- "More Profitable\nLess Difficult"
sch_tab$segment[sch_tab$sum <= reg_line &
sch_tab$mean >= median(sch_tab$mean)] <- "Less Profitable\nLess Difficult"
sch_tab$segment <- factor(sch_tab$segment,
levels = c("More Profitable\nLess Difficult",
"More Profitable\nMore Difficult",
"Less Profitable\nLess Difficult",
"Less Profitable\nMore Difficult"))
refs <- data.frame("labels" = c(paste("State:",sort(unique(schools$state))),
paste("Low grade:", sort(unique(schools$lowgrade))),
paste("High grade:", sort(unique(schools$highgrade))),
paste("Income:", dollar(sort(unique(schools$income))))),
"variables" = c(rep("state",length(unique(schools$state))),
rep("lowgrade", length(unique(schools$lowgrade))),
rep("highgrade", length(unique(schools$highgrade))),
rep("income", length(unique(schools$income)))),
"values" = c(sort(unique(schools$state)),
sort(unique(schools$lowgrade)),
sort(unique(schools$highgrade)),
sort(unique(schools$income))),
stringsAsFactors = FALSE)
# Define server logic required to plot various microsegments
shinyServer(function(input, output) {
sch_table <- reactive(function() {
df <- sch_tab
reward2 <- refs[refs$labels %in% input$reward,]
risk2 <- refs[refs$labels %in% input$risk,]
df$segment2[(df$state %in% reward2[reward2$variables == "state", "values"] |
df$lowgrade %in% reward2[reward2$variables == "lowgrade", "values"] |
df$highgrade %in% reward2[reward2$variables == "highgrade", "values"] &
df$income %in% reward2[reward2$variables == "income", "values"]) &
(df$state %in% risk2[risk2$variables == "state", "values"] |
df$lowgrade %in% risk2[risk2$variables == "lowgrade", "values"] |
df$highgrade %in% risk2[risk2$variables == "highgrade", "values"] |
df$income %in% risk2[risk2$variables == "income", "values"])] <- "More Profitable\nLess Difficult"
df$segment2[(df$state %in% reward2[reward2$variables == "state", "values"] |
df$lowgrade %in% reward2[reward2$variables == "lowgrade", "values"] |
df$highgrade %in% reward2[reward2$variables == "highgrade", "values"] |
df$income %in% reward2[reward2$variables == "income", "values"]) &
!(df$state %in% risk2[risk2$variables == "state", "values"] |
df$lowgrade %in% risk2[risk2$variables == "lowgrade", "values"] |
df$highgrade %in% risk2[risk2$variables == "highgrade", "values"] |
df$income %in% risk2[risk2$variables == "income", "values"])] <- "More Profitable\nMore Difficult"
df$segment2[!(df$state %in% reward2[reward2$variables == "state", "values"] |
df$lowgrade %in% reward2[reward2$variables == "lowgrade", "values"] |
df$highgrade %in% reward2[reward2$variables == "highgrade", "values"] |
df$income %in% reward2[reward2$variables == "income", "values"]) &
(df$state %in% risk2[risk2$variables == "state", "values"] |
df$lowgrade %in% risk2[risk2$variables == "lowgrade", "values"] |
df$highgrade %in% risk2[risk2$variables == "highgrade", "values"] |
df$income %in% risk2[risk2$variables == "income", "values"])] <- "Less Profitable\nLess Difficult"
df
})
output$segplot <- reactivePlot(function() {
df <- sch_table()
df <- melt(df, id.vars = c("state", "lowgrade", "highgrade", "income", "n",
"sum", "mean"), variable.name = "Version",
value.name = "Segment")
df$Version <- as.character(df$Version)
df$Version[df$Version == "segment"] <- "Optimized"
df$Version[df$Version == "segment2"] <- "Customized"
df$Version <- factor(df$Version, levels = c("Optimized", "Customized"))
df$Segment <- factor(df$Segment,
levels = c("More Profitable\nLess Difficult",
"More Profitable\nMore Difficult",
"Less Profitable\nLess Difficult",
"Less Profitable\nMore Difficult"))
out <- ggplot(df, aes(x = mean, y = sum, color = Segment)) +
geom_point(size=2) +
scale_color_manual(values = c("blue", "green", "red", "black")) +
scale_x_continuous("Avg. Revenue (Ease of Sale)", labels = dollar) +
scale_y_continuous("Tot. Revenue (Profitability)", labels = dollar) +
facet_grid(Version~.) +
ggtitle("Segmentation Comparison:\nStatistically Optimized vs. Individually Customized Solutions") +
theme_bw()
print(out)
})
output$segtable1 <- reactiveTable(function() {
df <- sch_table()
df$Optimized <- df$segment
ddply(df,
.variables = "Optimized",
function(df){
c("Tot. Revenue" = dollar_format(0)(sum(df$sum)),
"Avg. Revenue" = dollar_format(0)(sum(df$mean)),
"# Schools" = comma(sum(df$n)))
})
})
output$segtable2 <- reactiveTable(function() {
df <- sch_table()
df$Customized <- df$segment2
ddply(df,
.variables = "Customized",
function(df){
c("Tot. Revenue" = dollar_format(0)(sum(df$sum)),
"Avg. Revenue" = dollar_format(0)(sum(df$mean)),
"# Schools" = comma(sum(df$n)))
})
})
})
library(shiny)
library(scales)
state <- c("CA", "WA", "OR", "AZ", "NV", "UT")
lowgrade <- c(0, 1, 5, 7, 9)
highgrade <- c(5,6,8,9,12)
income <- (1:10) * 10000
shinyUI(pageWithSidebar(
# Application title
headerPanel("Microsegment Explorer"),
sidebarPanel(
checkboxGroupInput("reward", "Select microsegments you expect to be profitable:",
c(paste("State:",sort(unique(state))),
paste("Low grade:", sort(unique(lowgrade))),
paste("High grade:", sort(unique(highgrade))),
paste("Income:", dollar(sort(unique(income)))))),
checkboxGroupInput("risk", "Select microsegments you expect to be easy to sell:",
c(paste("State:",sort(unique(state))),
paste("Low grade:", sort(unique(lowgrade))),
paste("High grade:", sort(unique(highgrade))),
paste("Income:", dollar(sort(unique(income))))))
),
mainPanel(
plotOutput("segplot", width = "80%", height = "500px"),
tableOutput("segtable1"),
tableOutput("segtable2")
)
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment