fn <- read_sheet('https://docs.google.com/spreadsheets/d/1wFb31JqI0QDXmijN82p_oJt3Km28_WsI0Fa8VfFjkp0/edit#gid=0')
head(fn)
## # A tibble: 6 × 14
##   place  elim accuracy damage_to_p distance_m mats_used damage_ta…¹  hits player
##   <dbl> <dbl>    <dbl>       <dbl>      <dbl>     <dbl>       <dbl> <dbl> <chr> 
## 1    27     0        0          NA        778       110         205     0 claire
## 2    10     6       13          NA       3000       370         430    48 brend…
## 3     8     1        9          NA       2000       210         201    10 claire
## 4    25     1        9          NA       1000        40         313     8 brend…
## 5    49     3       26          NA        473        20         247    19 brend…
## 6    70     0        0          NA        103         0         114     0 brend…
## # … with 5 more variables: date <dttm>, account <chr>, game <chr>, build <chr>,
## #   ...14 <dbl>, and abbreviated variable name ¹​damage_taken
nrow(fn)
## [1] 210
str(fn)
## tibble [210 × 14] (S3: tbl_df/tbl/data.frame)
##  $ place       : num [1:210] 27 10 8 25 49 70 15 29 99 99 ...
##  $ elim        : num [1:210] 0 6 1 1 3 0 1 4 1 0 ...
##  $ accuracy    : num [1:210] 0 13 9 9 26 0 23 9 0 13 ...
##  $ damage_to_p : num [1:210] NA NA NA NA NA NA 303 433 0 NA ...
##  $ distance_m  : num [1:210] 778 3000 2000 1000 473 103 2000 2000 39 10 ...
##  $ mats_used   : num [1:210] 110 370 210 40 20 0 100 39 0 0 ...
##  $ damage_taken: num [1:210] 205 430 201 313 247 114 341 226 102 105 ...
##  $ hits        : num [1:210] 0 48 10 8 19 0 18 18 0 1 ...
##  $ player      : chr [1:210] "claire" "brendan" "claire" "brendan" ...
##  $ date        : POSIXct[1:210], format: "2022-11-01" "2022-11-01" ...
##  $ account     : chr [1:210] "grapedaddyz" "grapedaddyz" "grapedaddyz" "grapedaddyz" ...
##  $ game        : chr [1:210] "solos" "solos" "solos" "solos" ...
##  $ build       : chr [1:210] NA NA NA NA ...
##  $ ...14       : num [1:210] NA NA NA NA NA NA NA NA NA NA ...

plot all correlations

ggpairs(fn[,c(1:9)])
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

damage dealt

ggplot(fn, aes(x=player, y=damage_to_p, fill=player)) + geom_violin() + theme_bw()
## Warning: Removed 14 rows containing non-finite values (`stat_ydensity()`).

kill to death ratio

the standard way to measure success in video games.

here - KDT= eliminations over damage taken (because once you die you are out of the game)

and DDDT= damage dealt over damage taken

fn$KDT<- (fn$elim/fn$damage_taken)*100
fn$DDDT<- (fn$damage_to_p/fn$damage_taken)
ggplot(fn, aes(x=player, y=KDT, fill=player)) + geom_violin() + theme_bw()
## Warning: Removed 3 rows containing non-finite values (`stat_ydensity()`).

ggplot(fn, aes(x=player, y=DDDT, fill=player)) + geom_violin() + theme_bw()
## Warning: Removed 16 rows containing non-finite values (`stat_ydensity()`).

efficiency

what is the average amount of damage dealt per each hit?

for only those games with nonzero hits

# fn[fn=="Inf"]<- NA
#fn[fn=="NaN"]<- NA
fn$effic<- ifelse(fn$hits>0, fn$damage_to_p/fn$hits, 0)
ggplot(fn, aes(x=player, y=effic, fill=player)) + geom_violin() + theme_bw()
## Warning: Removed 13 rows containing non-finite values (`stat_ydensity()`).

accuracy

ggplot(fn, aes(x=player, y=accuracy, fill=player)) + geom_violin() + theme_bw()
## Warning: Removed 1 rows containing non-finite values (`stat_ydensity()`).

creating a variable that is accuracy divided by place for games with nonzero hits. this variable attempts to capture accuracy over time in a game. there may be games where you have very high accuracy, but are eliminated almost immediately (e.g. 80% acc/98th place = .816). this is not as impressive as having very high accuracy on a higher (lower) place game (e.g. 80% acc/ 5th place = 16). it does not make sense to include games with 0 hits and therefore 0% accuracy in this statistic.

fn$acc_dur<- ifelse(fn$hits>0, (fn$accuracy/fn$place), NA)
ggplot(fn, aes(x=player, y=acc_dur, fill=player)) + geom_violin() + theme_bw()
## Warning: Removed 21 rows containing non-finite values (`stat_ydensity()`).

does efficiency predict damage dealt to damage taken ratio?

ggplot(fn, aes(x=effic, y=DDDT, shape=player,color=player)) + 
  geom_point()+
  geom_smooth(method=lm)
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 16 rows containing non-finite values (`stat_smooth()`).
## Warning: Removed 16 rows containing missing values (`geom_point()`).

do both efficiency and accuracy predict finish?

m2<-(lmer(place~acc_dur+effic+(1|player), data=fn))
## boundary (singular) fit: see help('isSingular')
summary(m2)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: place ~ acc_dur + effic + (1 | player)
##    Data: fn
## 
## REML criterion at convergence: 1604.3
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -1.4167 -0.7764 -0.2964  0.6272  2.8450 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  player   (Intercept)   0.0     0.00   
##  Residual             490.7    22.15   
## Number of obs: 178, groups:  player, 3
## 
## Fixed effects:
##             Estimate Std. Error       df t value Pr(>|t|)    
## (Intercept)  41.2378     3.5744 175.0000  11.537  < 2e-16 ***
## acc_dur      -2.7394     0.4259 175.0000  -6.432 1.16e-09 ***
## effic        -0.2129     0.1268 175.0000  -1.679   0.0949 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##         (Intr) acc_dr
## acc_dur -0.216       
## effic   -0.848 -0.046
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')

only accuracy (accuracy/place) significantly predicts place, controlling for each player as they might have different playing tendencies.

randoms <- ranef(m2)
dotplot(randoms)
## $player

do efficiency and accuracy predict damage dealt to damage taken?

m1<-(lmer(DDDT~acc_dur+effic+(1|player), data=fn))

summary(m1)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: DDDT ~ acc_dur + effic + (1 | player)
##    Data: fn
## 
## REML criterion at convergence: 588.8
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.6679 -0.6623 -0.1495  0.4529  4.3226 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  player   (Intercept) 0.2021   0.4495  
##  Residual             1.4484   1.2035  
## Number of obs: 178, groups:  player, 3
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept) 7.164e-01  3.281e-01 3.892e+00   2.184   0.0962 .  
## acc_dur     1.479e-01  2.328e-02 1.736e+02   6.352 1.80e-09 ***
## effic       2.927e-02  6.904e-03 1.734e+02   4.240 3.63e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##         (Intr) acc_dr
## acc_dur -0.112       
## effic   -0.499 -0.048

both accuracy (accuracy/place) and efficiency significantly predict damage dealt to damage taken, controlling for each player.

randoms <- ranef(m1)
dotplot(randoms)
## $player

how does distance relate to place?

fn$place_cat<- ifelse(fn$place<6, "top 5", ifelse(fn$place<21, "top 20", ifelse(fn$place<51, "top 50", ifelse(fn$place<76, "top 75", "top 100"))))
ggplot(fn, aes(x=distance_m, color=place_cat)) + geom_density(alpha=.3)
## Warning: Removed 2 rows containing non-finite values (`stat_density()`).

the games with the highest finishes (top 5) clearly involve the most running!

do the three players differ significantly on accuracy?

tapply(fn$acc_dur, fn$player, mean, na.rm=T)
##  brendan   claire     mike 
## 2.826538 1.537823 1.740210
fn$BvAll<- (fn$player=="brendan")*-2/3 + (fn$player=="claire")*1/3 + (fn$player=="mike")*1/3
fn$MvC<- (fn$player=="brendan")*0 + (fn$player=="claire")*-1/2 + (fn$player=="mike")*1/2

mcSummary(lm(acc_dur~BvAll+MvC, data=fn))
## lm(formula = acc_dur ~ BvAll + MvC, data = fn)
## 
## Omnibus ANOVA
##                  SS  df     MS EtaSq    F     p
## Model        66.661   2 33.331 0.012 1.16 0.316
## Error      5346.319 186 28.744                 
## Corr Total 5412.980 188 28.792                 
## 
##   RMSE AdjEtaSq
##  5.361    0.002
## 
## Coefficients
##                Est StErr      t  SSR(3) EtaSq   tol CI_2.5 CI_97.5     p
## (Intercept)  2.035 0.478  4.261 521.799 0.089    NA  1.093   2.977 0.000
## BvAll       -1.188 0.834 -1.424  58.248 0.011 0.932 -2.833   0.458 0.156
## MvC          0.202 1.345  0.150   0.651 0.000 0.932 -2.451   2.856 0.881

no, there are no significant differences in accuracy among players.

what about efficiency?

tapply(fn$effic, fn$player, mean, na.rm=T)
##  brendan   claire     mike 
## 22.56149 21.56334 19.57958
mcSummary(lm(effic~BvAll+MvC, data=fn))
## lm(formula = effic ~ BvAll + MvC, data = fn)
## 
## Omnibus ANOVA
##                   SS  df      MS EtaSq     F     p
## Model        197.953   2  98.977 0.005 0.474 0.623
## Error      40482.361 194 208.672                  
## Corr Total 40680.314 196 207.553                  
## 
##    RMSE AdjEtaSq
##  14.445   -0.005
## 
## Coefficients
##                Est StErr      t    SSR(3) EtaSq  tol CI_2.5 CI_97.5     p
## (Intercept) 21.235 1.238 17.153 61399.642 0.603   NA 18.793  23.676 0.000
## BvAll       -1.990 2.182 -0.912   173.493 0.004 0.93 -6.294   2.314 0.363
## MvC         -1.984 3.470 -0.572    68.212 0.002 0.93 -8.827   4.859 0.568

no, there are no significant differences between players on efficiency.

what about DDDT?

tapply(fn$DDDT, fn$player, mean, na.rm=T)
##  brendan   claire     mike 
## 2.022930 1.013206 1.579484
mcSummary(lm(DDDT~BvAll+MvC, data=fn))
## lm(formula = DDDT ~ BvAll + MvC, data = fn)
## 
## Omnibus ANOVA
##                 SS  df     MS EtaSq     F p
## Model       36.265   2 18.133 0.086 9.031 0
## Error      383.484 191  2.008              
## Corr Total 419.749 193  2.175              
## 
##   RMSE AdjEtaSq
##  1.417    0.077
## 
## Coefficients
##                Est StErr      t  SSR(3) EtaSq   tol CI_2.5 CI_97.5     p
## (Intercept)  1.539 0.122 12.591 318.273 0.454    NA  1.298   1.780 0.000
## BvAll       -0.727 0.215 -3.375  22.864 0.056 0.937 -1.151  -0.302 0.001
## MvC          0.566 0.343  1.653   5.485 0.014 0.937 -0.109   1.242 0.100

there are, however, significant differences in damage dealt to damage taken between players. namely, brendan has a significantly higher DDDT ratio than mike and claire. mike and claire do not significantly differ.

or place?

tapply(fn$place, fn$player, mean, na.rm=T)
##  brendan   claire     mike 
## 32.71654 32.03571 43.96296
mcSummary(lm(place~BvAll+MvC, data=fn))
## lm(formula = place ~ BvAll + MvC, data = fn)
## 
## Omnibus ANOVA
##                    SS  df       MS EtaSq    F     p
## Model        3105.237   2 1552.618 0.019 2.03 0.134
## Error      158306.687 207  764.767                 
## Corr Total 161411.924 209  772.306                 
## 
##    RMSE AdjEtaSq
##  27.654     0.01
## 
## Coefficients
##                Est StErr      t     SSR(3) EtaSq   tol CI_2.5 CI_97.5     p
## (Intercept) 36.238 2.309 15.691 188295.957 0.543    NA 31.685  40.792 0.000
## BvAll        5.283 4.064  1.300   1292.183 0.008 0.922 -2.730  13.295 0.195
## MvC         11.927 6.479  1.841   2591.518 0.016 0.922 -0.847  24.701 0.067

there do not seem to be significant differences in finish between the group either.

averages by day

fn$date2 <- as.Date(as.character(fn$date), format= "%m%d%y")
fn$date2<- mdy(fn$date)
## Warning: All formats failed to parse. No formats found.
day<- fn %>% group_by(player, date) %>%
 summarise_at(vars("accuracy", "place", "effic"), mean, na.rm=T)
day
## # A tibble: 45 × 5
## # Groups:   player [3]
##    player  date                accuracy place effic
##    <chr>   <dttm>                 <dbl> <dbl> <dbl>
##  1 brendan 2022-11-01 00:00:00     18.1  51.1  8.02
##  2 brendan 2022-11-03 00:00:00     27.2  25   17.7 
##  3 brendan 2022-11-06 00:00:00     24.1  19.4 30.9 
##  4 brendan 2022-11-07 00:00:00     34.5  25.8 32.0 
##  5 brendan 2022-11-08 00:00:00     15.6  29   26.3 
##  6 brendan 2022-11-10 00:00:00     14.1  47.2 15.3 
##  7 brendan 2022-11-13 00:00:00     19.1  16.4 27.4 
##  8 brendan 2022-11-15 00:00:00     22.7  31.2 20.1 
##  9 brendan 2022-12-01 00:00:00     23.5  29.9 24.0 
## 10 brendan 2022-12-06 00:00:00     32.5  15   28.7 
## # … with 35 more rows
ggplot(day, aes(x=date, y=place, colour=player)) +
  facet_wrap(~player)+
  geom_line() + 
  xlab("")+
  theme(axis.text.x = element_text(angle = 75, hjust=1))

ggplot(day, aes(x=date, y=accuracy, colour=player)) +
  facet_wrap(~player)+
  geom_line() + 
  xlab("")+
  theme(axis.text.x = element_text(angle = 75, hjust=1))

ggplot(day, aes(x=date, y=effic, colour=player)) +
  facet_wrap(~player)+
  geom_line() + 
  xlab("")+
  theme(axis.text.x = element_text(angle = 75, hjust=1))

are there any differences in xbox gamertags?

differences might occur if a certain username is a higher level, or has a propensity to be in a harder or easier lobby.

ggplot(fn, aes(x = place, y = account, group = account, fill=account)) + 
  geom_density_ridges() +
  facet_wrap(~game)
## Picking joint bandwidth of 6.49
## Picking joint bandwidth of 11.6

ggplot(fn, aes(x = DDDT, y = account, group = account, fill=account)) + 
  geom_density_ridges() +
  facet_wrap(~game)
## Picking joint bandwidth of 0.572
## Picking joint bandwidth of 0.463
## Warning: Removed 16 rows containing non-finite values (`stat_density_ridges()`).

ggplot(fn, aes(x = elim, y = account, group = account, fill=account)) + 
  geom_density_ridges() +
  facet_wrap(~game)
## Picking joint bandwidth of 1.3
## Picking joint bandwidth of 0.741

ggplot(fn, aes(x = damage_to_p, y = account, group = account, fill=account)) + 
  geom_density_ridges() +
  facet_wrap(~game)
## Picking joint bandwidth of 217
## Picking joint bandwidth of 161
## Warning: Removed 14 rows containing non-finite values (`stat_density_ridges()`).

sensivity analysis to see if there are differences in game type: solos vs duos

mcSummary(lm(place~game, data=fn))
## lm(formula = place ~ game, data = fn)
## 
## Omnibus ANOVA
##                    SS  df       MS EtaSq      F p
## Model        9939.894   1 9939.894 0.062 13.649 0
## Error      151472.029 208  728.231               
## Corr Total 161411.924 209  772.306               
## 
##    RMSE AdjEtaSq
##  26.986    0.057
## 
## Coefficients
##                Est StErr     t   SSR(3) EtaSq tol CI_2.5 CI_97.5     p
## (Intercept) 16.793 5.011 3.351 8178.241 0.051  NA  6.914  26.672 0.001
## gamesolos   19.942 5.398 3.695 9939.894 0.062  NA  9.301  30.583 0.000
ggplot(fn, aes(x=game, y=place, fill=game)) + geom_violin() + theme_bw() +
  facet_wrap(~player)
## Warning: Groups with fewer than two data points have been dropped.

mcSummary(lm(acc_dur~game, data=fn))
## lm(formula = acc_dur ~ game, data = fn)
## 
## Omnibus ANOVA
##                 SS  df     MS EtaSq     F     p
## Model        15.77   1 15.770 0.003 0.546 0.461
## Error      5397.21 187 28.862                  
## Corr Total 5412.98 188 28.792                  
## 
##   RMSE AdjEtaSq
##  5.372   -0.002
## 
## Coefficients
##                Est StErr      t  SSR(3) EtaSq tol CI_2.5 CI_97.5     p
## (Intercept)  3.091 1.054  2.934 248.472 0.044  NA  1.013   5.170 0.004
## gamesolos   -0.839 1.135 -0.739  15.770 0.003  NA -3.077   1.399 0.461
ggplot(fn, aes(x=game, y=acc_dur, fill=game)) + geom_violin() + theme_bw() +
  facet_wrap(~player)
## Warning: Removed 21 rows containing non-finite values (`stat_ydensity()`).
## Warning: Groups with fewer than two data points have been dropped.

mcSummary(lm(effic~game, data=fn))
## lm(formula = effic ~ game, data = fn)
## 
## Omnibus ANOVA
##                   SS  df      MS EtaSq    F     p
## Model        500.681   1 500.681 0.012 2.43 0.121
## Error      40179.634 195 206.049                 
## Corr Total 40680.314 196 207.553                 
## 
##    RMSE AdjEtaSq
##  14.354    0.007
## 
## Coefficients
##                Est StErr      t    SSR(3) EtaSq tol  CI_2.5 CI_97.5     p
## (Intercept) 25.742 2.666  9.657 19216.214 0.324  NA  20.485  30.999 0.000
## gamesolos   -4.499 2.886 -1.559   500.681 0.012  NA -10.192   1.193 0.121
ggplot(fn, aes(x=game, y=effic, fill=game)) + geom_violin() + theme_bw() +
  facet_wrap(~player)
## Warning: Removed 13 rows containing non-finite values (`stat_ydensity()`).
## Warning: Groups with fewer than two data points have been dropped.

interestingly, there are significant differences in finish between solos and duos, but not accuracy or efficiency.