Goals

This week I hope to finally finish reproducing Table 1 from my group’s COVID paper. I also hope to test the rest of my group’s code to see if I can reproduce everything else. If I get time, I also hope to try out a new package which allows for the calculation of effect sizes.

Progress

Finishing Table 1

I have finally managed to completely reproduce Table 1 from the COVID paper. Reproducing the results wasn’t so hard (as seen in my success in previous weeks), but producing a table which resembles the one in the paper was more challenging. This week, instead of immediately dividing the data into positive and negative emotions, I carried out the data wrangling on ALL of the emotions to begin with. I also added comments to all of my code to help with the writing of the verification report.

Here is an image of Table 1 for reference:

library(tidyverse) # Allows for easy data wrangling with shared language across packages
library(ggplot2) # Allows for detailed data visualisation
library(here) # Allows for construction of a path to project files
library(dplyr) # Allows for simple data manipulation
library(papaja) # Allows for APA formatting of results and tables
library(psych) # Includes "describe" function (M and SD)

master <- read.csv("AgeAdvantagesEmotionCovid_Data.csv", header = TRUE)

# Table 1 - Mean Frequencies of Emotions

## Name, Mean and SD

### Select the frequencies of each emotion from master data set.
emot <- master %>%
  select(f_calm, f_qui, f_app, f_int, f_cont, f_hap, f_rela, f_pea,
         f_ener, f_aff, f_amu, f_acc, f_joy, f_pro, f_reli, f_exc,
         f_conc, f_anx, f_bor, f_fru, f_irr, f_sad, f_lon, f_fear,
         f_ang, f_dis, f_gui, f_emb, f_sha)

### Create a new data frame with the descriptives (M and SD) for the emotions.
emot_des <- emot %>%
  summarise(
    across(.cols = everything(), na.rm = TRUE, list(M = mean, SD = sd)))

### Rename the emotions to table-friendly names.
emot_des <- emot_des %>%
  rename(Calm = f_calm_M, Quiet = f_qui_M, Appreciative = f_app_M,
         Interested = f_int_M, Content = f_cont_M, Happy = f_hap_M,
         Relaxed = f_rela_M, Peaceful = f_pea_M, Energetic = f_ener_M,
         Affectionate = f_aff_M, Amused = f_amu_M, Accomplished = f_acc_M,
         Joyful = f_joy_M, Proud = f_pro_M, Relieved = f_reli_M,
         Excited = f_exc_M, Concerned = f_conc_M, "Anxious/worried" = f_anx_M,
         Bored = f_bor_M, Frustrated = f_fru_M, Irritated = f_irr_M,
         Sad = f_sad_M, Lonely = f_lon_M, Fearful = f_fear_M,
         Angry = f_ang_M, Disgusted = f_dis_M, Guilty = f_gui_M,
         Embarrassed = f_emb_M, Ashamed = f_sha_M)

### Pivot the descriptive twice - one creates two variable with the name and mean of each emotion, the other creates the SD.
emot_pivot1 <- emot_des %>%
  select(-starts_with("f_")) %>%
  pivot_longer(cols = everything(), 
               names_to = "Valence and emotion",
               values_to = "M")

emot_pivot2 <- emot_des %>%
  select(starts_with("f_")) %>%
  pivot_longer(cols = everything(),
               names_to = NULL,
               values_to = "SD")

### Bind them together to create table-friendly descriptive stats.
emot_des_table <- bind_cols(emot_pivot1, emot_pivot2)

### Create lower and upper 95% CI limits
n <- 945; se <- emot_des_table$SD / sqrt(n)
emot_des_table <- emot_des_table %>%
  mutate(lower_CI = M - qt(1 - (0.05 / 2), n - 1) * se,
         upper_CI = M + qt(1 - (0.05 / 2), n - 1) * se)

### Round CIs to 2 d.p. (can't do this above because of non-numeric variable)
emot_des_table$lower_CI <- format(round(emot_des_table$lower_CI, 2), nsmall = 2)
emot_des_table$upper_CI <- format(round(emot_des_table$upper_CI, 2), nsmall = 2)

### Combine the CIs into one column
emot_des_table <- emot_des_table %>%
  unite(col = "95% CI", 
        lower_CI:upper_CI,
        sep = ", ") %>%
  mutate("95% CI" = paste0("[", `95% CI`, "]"))

Quick side note - I also found a cool package online which comes with an addin that allows you to split chunks of code into two using any shortcut you like. You can find the instructions for downloading and using this package here.

Anyway, at this point, to make the table look like the one in the paper, the emotions need to be grouped under “positive” and “negative”. The apa_table() function allows for this using the list() function as long as the emotions are separated into two data frames.

### Split the data into positive/negative emotions
pos_emot_table <- emot_des_table %>%
  slice(1:16)

neg_emot_table <- emot_des_table %>%
  slice(17:29)

### Apply the apa_table function (NOTE: Only produces correct output in APA formatted markdown template which comes with the papaja package)
apa_table(list('Positive emotions' = pos_emot_table,
               'Negative emotions' = neg_emot_table), 
          caption = "Mean Frequencies of Emotions",
          note = "N = 945. CI = confidence interval",
          align = c('l', 'c', 'c', 'c'),
          font_size = "scriptsize")
(#tab:unnamed-chunk-2)
Mean Frequencies of Emotions
Valence and emotion M SD 95% CI
Positive emotions
   Calm 2.44 0.87 [2.39, 2.50]
   Quiet 2.43 0.87 [2.38, 2.49]
   Appreciative 2.40 0.93 [2.35, 2.46]
   Interested 2.28 0.83 [2.23, 2.33]
   Content 2.15 0.94 [2.09, 2.21]
   Happy 2.13 0.80 [2.08, 2.19]
   Relaxed 2.13 0.89 [2.07, 2.19]
   Peaceful 2.05 0.95 [1.99, 2.11]
   Energetic 1.90 0.80 [1.85, 1.95]
   Affectionate 1.89 0.86 [1.83, 1.94]
   Amused 1.87 0.72 [1.83, 1.92]
   Accomplished 1.84 0.87 [1.78, 1.89]
   Joyful 1.71 0.90 [1.65, 1.76]
   Proud 1.67 0.97 [1.61, 1.73]
   Relieved 1.48 0.88 [1.42, 1.53]
   Excited 1.46 0.79 [1.41, 1.51]
Negative emotions
   Concerned 2.23 0.91 [2.17, 2.29]
   Anxious/worried 2.00 1.06 [1.94, 2.07]
   Bored 1.88 1.12 [1.80, 1.95]
   Frustrated 1.85 0.93 [1.79, 1.90]
   Irritated 1.75 0.89 [1.70, 1.81]
   Sad 1.69 0.97 [1.63, 1.75]
   Lonely 1.55 1.25 [1.47, 1.63]
   Fearful 1.38 1.06 [1.31, 1.44]
   Angry 1.35 0.89 [1.29, 1.40]
   Disgusted 1.16 0.99 [1.10, 1.22]
   Guilty 0.63 0.87 [0.58, 0.69]
   Embarrassed 0.51 0.76 [0.47, 0.56]
   Ashamed 0.44 0.76 [0.40, 0.49]

Note. N = 945. CI = confidence interval

 

Once again, the HTML output is nice, but not nearly as nice as the APA style table produced in pdf format, pictured below.


Using other group members’ code

Today I managed to transfer the rest of my group’s code to my own verification script and produce the same output. However, I did have to change a few of the dataset names to suit my style of coding. I also had a bit of trouble loading the dataset initially because our data files are all named differently. It is rather ironic that I should come across a reproducabilty issue with our own work given the nature of this assignment!

Effect size package

The MOTE package (designed by Dr. Erin Buchanan) is a nifty package which can be used to calculate effect sizes in Rstudio. Considering I need to calculate an effect size for another assignment, I thought I might try it out.

library(MOTE)

The below function produces an effect size (and associated stats) for the results of an independent t-test. All you have to do is give the means, SDs and sample sizes for each group, as well as the alpha level. The output is pretty lengthy (22 different values). But if we just want the value for Cohen’s d, we can call it out specifically.

effectsize <- d.ind.t(m1 = 87, 
        m2 = 71, 
        sd1 = 12.9, 
        sd2 = 15.2, 
        n1 = 10, 
        n2 = 10, 
        a = 0.05)

effectsize$d
## [1] 1.134994

The MOTE package comes with a lot of really cool functions which I might have to try out, including an apa() function which formats decimals and leading zeroes for creating reports in scientific style. Instructions for the MOTE package and all of its functions (and the arguments of each function) can be found here.

Challenges and Successes

This week I encountered a couple of minor challenges. First, it was difficult figuring out how I could display all of the emotions, grouped under “positive” and “negative”, in Table 1. However, after a little investigation into the papaja package, I found an example table which used the list() function to do just that. Additionally, when knitting the table in PDF format, the bottom of it kept getting cut off, so I had to change the font of the table contents to get it to fit onto one page. I also had a few issues with using my group members’ code when their data files were named differently, and their object names were not consistent with my style of coding.

Having said that, I was also very successful this week. I managed to achieve all of my goals. I finally finished reproducing Table 1, and have gotten quite close to the original table. I also transferred all of my group members’ code into my own, and managed to produce all of the same results. On top of that, I also had some time to play around with the MOTE package for effect sizes and I hope to explore it more in the future.

Next Step

My next step is to begin working on my verification report. Perhaps I might also find some ways to refine my code even further.