inst/doc/kraljic.R

## ---- eval=FALSE---------------------------------------------------------
#  psc
#  ## # A tibble: 200 × 3
#  ##      PSC x_attribute y_attribute
#  ##    <chr>       <int>       <int>
#  ## 1   D233        3.01        4.84
#  ## 2   F352        4.34        5.64
#  ## 3   T713        3.37        4.30
#  ## 4   K833        2.67        5.53
#  ## 5   Q121        3.48        4.33
#  ## 6   C791        3.32        7.32
#  ## 7   Y207        3.48        5.42
#  ## 8   W439        2.47        3.35
#  ## 9   N290        1.66        4.02
#  ## 10  C251        1.00        7.47
#  ## # ... with 190 more rows

## ---- echo=FALSE, warning=FALSE, message=FALSE---------------------------
psc <- tibble::tibble(
  PSC = c("D233", "F352", "T713", "K833", "Q121", "C791", "Y207", "W439", "N290", "C251", "U115", "Y679", "P256","B272", "Y895", "D663", "D400", "S883", "G274", "S229", "V324", "C529", "H379", "S528", "Q844", "X925", "A202", "W483", "Q507", "X898", "T845", "F318", "Y357", "Y536", "R954", "Y416", "E103", "I425", "C305", "W936", "H489", "N923", "G904", "I329", "T636", "G220", "W441", "C432", "N429", "N527", "X253", "N376", "L595", "K472", "H824", "X945", "D604", "E997", "K815", "E817", "D655", "R315", "P402", "F754", "Y853", "K960", "T856", "Z840", "H423", "Q618", "S855", "U622", "Q410", "G641", "Q255", "B187", "B238", "K980", "V809", "O854", "B455", "J637", "C309", "H426", "F973", "P184", "N763", "G691", "T373", "V761", "V437", "Y396", "S405", "I418", "R631", "I364", "D442", "D353", "J313", "Q795", "O131", "O920", "Y670", "V906", "O977", "J164", "M578", "V879", "M450", "E908", "B666", "D994", "N741", "A261", "H986", "W685", "Z776", "Z821", "A859", "S961", "E928", "F520", "X634", "B875", "C284", "X262", "V177", "C877", "D623", "M607", "P171", "E580", "I440", "D581", "E370", "M667", "G230", "G626", "G783", "N915", "X119", "Q697", "M496", "S868", "F334", "R777", "P941", "N436", "W932", "E537", "T317", "K942", "D715", "M176", "F452", "V162", "D983", "H278", "V649", "M775", "T269", "T173", "O522", "W299", "G852", "P291", "X597", "U310", "Q541", "M375", "A365", "L979", "X283", "T962", "E808", "A363", "I617", "B829", "G698", "B188", "U646", "O288", "T127", "C901", "I116", "V870", "S346", "J758", "S965", "E619", "I682", "M354", "H562", "K482", "L568", "Z491", "A668", "T203", "J332", "G362"), 
  x_attribute = c(3.01, 4.34, 3.37, 2.67, 3.48, 3.32, 3.48, 2.47, 1.66, 1.00, 1.40, 2.99, 4.93, 1.62, 1.00, 3.42, 2.66, 1.31, 3.24, 1.45, 2.70, 1.61, 3.99, 2.40, 1.77, 3.92, 2.88, 2.75, 3.37, 2.53, 2.94, 4.68, 5.00, 4.01, 1.18, 1.00, 4.46, 3.54, 1.00, 1.43, 1.00, 2.57, 2.41, 1.90, 3.39, 3.43, 2.84, 4.65, 3.95, 3.01, 1.69, 2.11, 3.73, 3.84, 1.33, 4.18, 3.25, 5.00, 2.85, 4.31, 2.95, 2.52, 5.00, 2.49, 1.64, 3.96, 2.57, 4.74, 2.46, 3.13, 4.32, 1.41, 4.66, 3.05, 4.95, 1.71, 2.03, 3.18, 2.05, 1.89, 2.42, 4.66, 4.12, 5.00, 3.46, 3.56, 3.30, 2.01, 4.22, 3.86, 4.24, 2.15, 3.28, 4.21, 2.35, 2.36, 2.83, 2.60, 2.60, 1.16, 2.37, 4.48, 3.98, 1.00, 3.88, 1.22, 2.31, 3.82, 2.57, 4.75, 3.51, 4.58, 3.82, 3.83, 2.67, 3.95, 4.53, 3.70, 3.75, 3.47, 3.18, 4.21, 5.00, 4.00, 4.91, 2.70, 2.28, 1.00, 1.00, 2.95, 3.40, 4.06, 1.22, 1.61, 3.48, 3.53, 2.41, 3.42, 2.60, 3.87, 2.62, 5.00, 3.76, 1.64, 2.68, 1.78, 1.56, 2.67, 3.80, 2.98, 2.46, 4.81, 4.03, 3.22, 5.00, 2.74, 1.86, 4.43, 3.31, 2.28, 4.01, 3.99, 2.21, 2.25, 2.72, 3.31, 4.54, 3.67, 4.19, 2.23, 3.49, 3.80, 5.00, 2.28, 3.97, 3.42, 2.10, 1.88, 2.02, 3.89, 1.00, 5.00, 2.60, 3.80, 4.32, 5.00, 3.01, 4.17, 2.46, 5.00, 2.38, 2.37, 2.13, 2.41, 1.74, 1.00, 3.78, 1.00, 3.07, 2.29),
  y_attribute = c(4.84, 5.64, 4.30, 5.53, 4.33, 7.32, 5.42, 3.35, 4.02, 7.47, 6.58, 1.00, 3.04, 2.46, 4.91, 5.49, 4.72, 5.73, 8.98, 7.57, 3.30, 2.65, 4.76, 5.75, 5.76, 4.60, 2.44, 7.98, 8.82, 5.11, 3.44, 4.23, 6.55, 1.75, 4.80, 6.32, 7.71, 3.50, 5.49, 6.52, 5.06, 2.48, 4.45, 5.60, 6.58, 2.79, 6.58, 6.05, 7.60, 3.51, 4.75, 4.83, 4.12, 7.88, 4.45, 6.83, 1.34, 1.53, 4.04, 6.55, 6.64, 6.24, 5.82, 5.67, 4.97, 4.04, 5.21, 4.87, 5.52, 4.02, 4.89, 5.46, 5.54, 1.40, 6.41, 2.46, 5.53, 6.90, 6.47, 5.93, 4.66, 3.15, 2.66, 5.58, 3.91, 5.09, 6.18, 2.63, 6.93, 1.20, 4.67, 6.77, 5.19, 6.15, 2.38, 6.78, 5.91, 5.74, 4.51, 4.56, 6.65, 4.32, 3.76, 6.34, 6.74, 5.23, 1.00, 5.03, 4.39, 7.11, 6.11, 4.52, 3.93, 6.76, 4.34, 6.46, 5.05, 7.75, 1.54, 1.10, 7.36, 4.61, 5.19, 4.92, 2.07, 6.54, 5.81, 8.37, 6.50, 4.22, 3.00, 6.68, 4.99, 4.88, 5.27, 3.71, 1.36, 3.37, 6.80, 4.70, 5.27, 4.19, 7.50, 2.86, 1.18, 6.96, 4.40, 3.98, 3.58, 3.00, 3.06, 1.50, 4.17, 4.42, 4.36, 6.96, 5.51, 3.86, 7.40, 5.63, 4.08, 5.04, 7.29, 9.54, 2.72, 5.77, 6.23, 5.50, 4.32, 3.00, 3.30, 6.41, 4.52, 4.74, 6.46, 2.99, 6.77, 6.16, 6.28, 3.63, 10.00, 5.00, 8.18, 4.76, 7.30, 5.88, 8.21, 7.48, 6.02, 3.65, 7.21, 2.66, 5.15, 6.38, 5.95, 5.74, 4.30, 2.96, 5.89, 2.63)
)

## ---- eval=FALSE---------------------------------------------------------
#  SAVF_preferred_rho(desired_x = c(3, 4, 5),
#                     desired_v = c(.8, .9, 1),
#                     x_low = 1,
#                     x_high = 5,
#                     rho_low = 0,
#                     rho_high = 1)
#  ## [1] 0.6531

## ---- echo=FALSE---------------------------------------------------------
SAVF_score <- function(x, x_low, x_high, rho){

  # return error if x_low is not less than x_high
  if(x_low >= x_high){
    stop("`x_low` must be less than `x_high`", call. = FALSE)
  }

  # return error if rho is not a single value
  if (length(rho) != 1) {
    stop("`rho` must be a numeric value of length 1", call. = FALSE)
  }

  # generate SAVF values
  value <- (1 - exp(-rho * (x - x_low))) / (1 - exp(-rho * (x_high - x_low)))

  # return values
  return(value)

}

SAVF_plot <- function(desired_x, desired_v, x_low, x_high, rho){

  # return error if x_low is not less than x_high
  if(x_low >= x_high){
    stop("`x_low` must be less than `x_high`", call. = FALSE)
  }

  # return error if rho is not a single value
  if (length(rho) != 1) {
    stop("`rho` must be a numeric value of length 1", call. = FALSE)
  }

  # create string of x values
  x <- seq(x_low, x_high, by = (x_high - x_low) / 1000)
  v <- SAVF_score(x, x_low, x_high, rho)

  # create data frames to plot
  df <- data.frame(x = x, v = v)
  desired <- data.frame(x = desired_x, v = desired_v)

  ggplot2::ggplot(df, ggplot2::aes(x, v)) +
    ggplot2::geom_line() +
    ggplot2::geom_point(data = desired, ggplot2::aes(x, v), shape = 23, size = 2, fill = "white")

}

## ---- fig.align='center', fig.height=3, fig.width=6----------------------


SAVF_plot(desired_x = c(3, 4, 5),
          desired_v = c(.8, .9, 1),
          x_low = 1,
          x_high = 5,
          rho = 0.6531)

## ---- echo=FALSE---------------------------------------------------------
SAVF_plot_rho_error <- function(desired_x, desired_v, x_low, x_high, rho_low, rho_high){

  # return error if x_low is not less than x_high
  if(x_low >= x_high){
    stop("`x_low` must be less than `x_high`", call. = FALSE)
  }

  # return error if rho_low is not less than rho_high
  if(rho_low >= rho_high){
    stop("`rho_low` must be less than `rho_high`", call. = FALSE)
  }

  # compute sequence of rho values
  rho <- seq(rho_low, rho_high, by = (rho_high - rho_low) / 10000)
  rho <- rho[rho != 0]

  # compute deltas between preferred and fitted values
  delta <- sapply(rho, function(x) sum((SAVF_score(desired_x, x_low, x_high, x) - desired_v)^2))

  # return rho that produces smallest error
  true_rho <- rho[which(delta == min(delta))]

  # plot value
  df <- data.frame(rho = rho, delta = delta)
  ggplot2::ggplot(df, ggplot2::aes(rho, delta)) +
    ggplot2::geom_line() +
    ggplot2::geom_point(ggplot2::aes(true_rho, min(delta)), shape = 23, size = 2, fill = "white")

}

## ---- fig.align='center', fig.height=3, fig.width=6----------------------
SAVF_plot_rho_error(desired_x = c(3, 4, 5),
                    desired_v = c(.75, .9, 1),
                    x_low = 1,
                    x_high = 5,
                    rho_low = 0,
                    rho_high = 1)

## ---- echo=FALSE---------------------------------------------------------
SAVF_score <- function(x, x_low, x_high, rho){

  # return error if x_low is not less than x_high
  if(x_low >= x_high){
    stop("`x_low` must be less than `x_high`", call. = FALSE)
  }

  # return error if rho is not a single value
  if (length(rho) != 1) {
    stop("`rho` must be a numeric value of length 1", call. = FALSE)
  }

  # generate SAVF values
  value <- (1 - exp(-rho * (x - x_low))) / (1 - exp(-rho * (x_high - x_low)))

  # return values
  return(value)

}

## ---- collapse=TRUE, message=FALSE, warning=FALSE------------------------
# using dplyr to add a new variable while preserving existing data
library(dplyr)

# here we are assuming we found the appropriate rho value for the y attribute using
# the same process as mentioned above
psc <- psc %>%
  mutate(x_SAVF_score = SAVF_score(x_attribute, 1, 5, .653),
         y_SAVF_score = SAVF_score(y_attribute, 1, 10, .70))

psc

## ---- echo=FALSE---------------------------------------------------------
kraljic_matrix <- function(data, x, y){

  # return error if x or y are not numeric values
  x_col <- data[[deparse(substitute(x))]]
  y_col <- data[[deparse(substitute(y))]]

  if(!is.numeric(x_col) | !is.numeric(y_col)){
    stop("data for both column inputs must be numeric", call. = FALSE)
  }

  # plot Kraljic Matrix
  ggplot2::ggplot(data, ggplot2::aes_string(deparse(substitute(x)), deparse(substitute(y)))) +
    ggplot2::geom_point() +
    ggplot2::geom_vline(xintercept = .5) +
    ggplot2::geom_hline(yintercept = .5) +
    ggplot2::coord_cartesian(xlim = c(0,1), ylim = c(0,1)) +
    ggplot2::scale_x_reverse()
}

## ---- fig.align='center', fig.width=7, fig.height=5----------------------
kraljic_matrix(psc, x_SAVF_score, y_SAVF_score)

## ---- echo=FALSE---------------------------------------------------------
kraljic_quadrant <- function(x, y){

  ifelse(x > .5 & y >= .5, "Leverage",
         ifelse(x > .5 & y < .5, "Critical",
                ifelse(x <= .5 & y >= .5, "Strategic",
                       ifelse(x < .5 & y < .5, "Bottleneck", NA))))

}

## ---- collapse=TRUE------------------------------------------------------
psc %>%
  mutate(quadrant = kraljic_quadrant(x_SAVF_score, y_SAVF_score))

## ---- echo=FALSE---------------------------------------------------------
MAVF_score <- function(x, y, x_wt, y_wt){

  # return error if x and y are different lengths
  if(length(x) != length(y)){
    stop("`x` and `y` must be the same length", call. = FALSE)
  }

  # return error if x or y weights are not a single value
  if (length(x_wt) != 1 | length(y_wt) != 1) {
    stop("x and y weights must be numeric values of length 1", call. = FALSE)
  }

  x * x_wt + y * y_wt + (1 - x_wt - y_wt) * x * y

}

## ---- collapse=TRUE------------------------------------------------------
psc %>%
  mutate(MAVF = MAVF_score(x_SAVF_score, y_SAVF_score, 0.65, 0.35))

## ---- collapse=TRUE------------------------------------------------------
psc %>%
  mutate(MAVF = MAVF_score(x_SAVF_score, y_SAVF_score, 0.65, 0.35),
         quadrant = kraljic_quadrant(x_SAVF_score, y_SAVF_score)) %>%
  filter(quadrant == "Leverage") %>%
  top_n(10, wt = MAVF)

## ---- echo=FALSE---------------------------------------------------------
MAVF_sensitivity <- function(data, x, y, x_wt_min, x_wt_max, y_wt_min, y_wt_max){

  # return error if x_wt_min is not less than x_wt_max
  if(x_wt_min >= x_wt_max){
    stop("`x_wt_min` must be less than `x_wt_max`", call. = FALSE)
  }

  # return error if y_wt_min is not less than y_wt_max
  if(y_wt_min >= y_wt_max){
    stop("`y_wt_min` must be less than `y_wt_max`", call. = FALSE)
  }

  # create random wts
  x_wt <- runif(1000, min = x_wt_min, max = x_wt_max)
  y_wt <- runif(1000, min = y_wt_min, max = y_wt_max)
  w_wt <- 1 - x_wt - y_wt

  # parse out vectors from data
  x_col <- data[[deparse(substitute(x))]]
  y_col <- data[[deparse(substitute(y))]]

  # create vectors to fill
  Min. <- vector(mode = "numeric", length = nrow(data))
  `1st Qu.` <- vector(mode = "numeric", length = nrow(data))
  Median <- vector(mode = "numeric", length = nrow(data))
  Mean <- vector(mode = "numeric", length = nrow(data))
  `3rd Qu.` <- vector(mode = "numeric", length = nrow(data))
  Max. <- vector(mode = "numeric", length = nrow(data))
  Range <- vector(mode = "numeric", length = nrow(data))

  # loop through to compute values for each x y pair
  for(i in 1:nrow(data)){
    s <- summary(x_col[i] * x_wt + y_col[i] * y_wt + (1 - x_wt - y_wt) * x_col[i] * y_col[i])
    Min.[i] <- s[1]
    `1st Qu.`[i] <- s[2]
    Median[i] <- s[3]
    Mean[i] <- s[4]
    `3rd Qu.`[i] <- s[5]
    Max.[i] <- s[6]
    Range[i] <- s[6] - s[1]
  }

  # add new columns
  data$MAVF_Min <- Min.
  data$MAVF_1st_Q <- `1st Qu.`
  data$MAVF_Median <- Median
  data$MAVF_Mean <- Mean
  data$MAVF_3rd_Q <- `3rd Qu.`
  data$MAVF_Max <- Max.
  data$MAVF_Range <- Range


  # return data
  data

}

## ---- collapse=TRUE------------------------------------------------------
MAVF_sensitivity(psc,
                 x = x_SAVF_score,
                 y = y_SAVF_score,
                 x_wt_min = .55,
                 x_wt_max = .75,
                 y_wt_min = .25,
                 y_wt_max = .45) %>%
  select(PSC, starts_with("MAVF"))

Try the KraljicMatrix package in your browser

Any scripts or data that you put into this service are public.

KraljicMatrix documentation built on May 2, 2019, 2:32 p.m.