How to calculate the probability of being a median across a list using R?

Viewed 55

Say I have the follow dataset that shows a list of three observations for each state for a hypothetical experiment:

state <- c("Iowa", "Minnesota", "Illinois")
outcome <- list(c(5, 11, 11), c(3, 12, 8), c(9, 14, 2))
dat <- tibble(state, outcome)

Each row contains the state's name, as well as the results of an experiment that are aligned vertically by position. (The first row holds the results for the first experiment, the second row the second experiment, etc.) I'm trying to determine the probability of a state having the median value in an experiment. For example:

  • In the first experiment, Iowa had the median value of 5.
  • In the second experiment, Minnesota had the median value of 11.
  • In the third experiment, Minnesota had the median value of 8.

Therefore, we would assign the following probabilities to each state given our small sample:

  • Iowa's probability of being the median: 1 / 3 = 33%
  • Minnesota's probability of being the median: 2 / 3 = 67%
  • Illinois's probability of being the median: 0 / 3 = 0%

How does one calculate the probabilities of a state being the median using R? Thanks in advance.

2 Answers

Here's a tidyverse solution:

library(dplyr)
library(tidyr)

dat %>% 
  unnest(cols = outcome) %>% 
  group_by(state) %>% 
  mutate(experiment = seq(n())) %>% 
  group_by(experiment) %>% 
  mutate(is_median = as.numeric(outcome == median(outcome))) %>% 
  group_by(state) %>% 
  mutate(prob_median = scales::percent(sum(is_median)/length(is_median)))

#> # A tibble: 9 x 5
#> # Groups:   state [3]
#>   state     outcome experiment is_median prob_median
#>   <chr>       <dbl>      <int>     <dbl> <chr>      
#> 1 Iowa            5          1         1 33%        
#> 2 Iowa           11          2         0 33%        
#> 3 Iowa           11          3         0 33%        
#> 4 Minnesota       3          1         0 67%        
#> 5 Minnesota      12          2         1 67%        
#> 6 Minnesota       8          3         1 67%        
#> 7 Illinois        9          1         0 0%         
#> 8 Illinois       14          2         0 0%         
#> 9 Illinois        2          3         0 0%    

Here is a base R option using prop.table + factor

within(
  dat,
  media_prob <- prop.table(
    table(factor(
      state[sapply(
        asplit(do.call(rbind, outcome), 2),
        function(x) which(x == median(x))
      )],
      levels = state
    ))
  )
)

which gives

  state     outcome   media_prob
  <chr>     <list>    <table>
1 Iowa      <dbl [3]> 0.3333333
2 Minnesota <dbl [3]> 0.6666667
3 Illinois  <dbl [3]> 0.0000000
Related