#----------------------------------------------------------------------------------------------------------------
# 
#       A Comparison of Covariate Adjustment Approaches under Model Misspecification 
#                   in Individually Randomized Trials: Additional Files 
# 
#
#   This R file runs the Main Simulation and the three Extensions 
#               
#----------------------------------------------------------------------------------------------------------------


source("01_Generate.R")
source("02_Analyse.R")


#----------------------------------------------------------
#  Main Simulation
#----------------------------------------------------------

#  Simulate and analyse one dataset -----------------------
callfun_cts_normal <- function(n, sd=42, true_diff=40){
  
  
  ### Simulate a single dataset
  data <- gen_cts_normal(n, sd, true_diff)
  
  
  ### Analyse  ###
  
  # List of outcomes
  ylist <- c("y1", "y2", "y3", "y4", "y5", "y6", "y7")
  
  # Baseline covariates: x only
  
  
  ### T-test
  
  res_ttest <- NULL
  i <- 1
  for (var in ylist) {
    simr      <- cbind(outcome=i, fttest(data, var, "treat"))
    res_ttest <- rbind(res_ttest, simr)
    i <- i+1
  }
  
  
  ### ANCOVA
  
  res_ancova <- NULL
  i <- 1
  for (var in ylist) {
    simr       <- cbind(outcome=i,  fancova(data, var, "treat", "x"))
    res_ancova <- rbind(res_ancova, simr)
    i <- i+1
  }
  
  
  ### Splines
  
  # DF - 4
  res_spline4 <- NULL
  i <- 1
  for (var in ylist) {
    simr       <- cbind(outcome=i,  fspline(data, var, "treat", "x", 4))
    res_spline4 <- rbind(res_spline4, simr)
    i <- i+1
  }
  
  
  # DF - 20
  res_spline20 <- NULL
  i <- 1
  for (var in ylist) {
    simr       <- cbind(outcome=i,  fspline(data, var, "treat", "x", 20))
    res_spline20 <- rbind(res_spline20, simr)
    i <- i+1
  } 
  names(res_spline20) <- c("outcome", "spline2_diff", "spline2_se", "spline2_cl", "spline2_cu", "spline2_p")
  
  
  ### Correct model
  
  res_correct <- NULL
  i <- 1
  for (var in ylist) {
    simr       <- cbind(outcome=i,  fcorrect(data, var, "treat", "x"))
    res_correct <- rbind(res_correct, simr)
    i <- i+1
  }
  
  ### IPTW
  
  res_iptw <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running IPTW function
    temp <- try(fiptw(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_iptw  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_iptw  <- data.frame(outcome=i,  
                               iptw_diff=9999, iptw_se=9999, iptw_cl=9999, 
                               iptw_cu=9999, iptw_p=9999)
    }
    res_iptw <- rbind(res_iptw, simr_iptw)
    i <- i+1
  } 
  
  ### IPTW with splines 
  
  res_iptw_spline <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running IPTW function
    temp <- try(fiptw_spline(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_iptw  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_iptw  <- data.frame(outcome=i,  
                               iptw_diff=9999, iptw_se=9999, iptw_cl=9999, 
                               iptw_cu=9999, iptw_p=9999)
    }
    res_iptw_spline <- rbind(res_iptw_spline, simr_iptw)
    i <- i+1
  } 
  
  
  ### AIPTW
  
  res_aiptw <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running AIPTW function
    temp <- try(faiptw(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_aiptw  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_aiptw  <- data.frame(outcome=i,  
                                aiptw_diff=9999, aiptw_se=9999, aiptw_cl=9999, 
                                aiptw_cu=9999, aiptw_p=9999)
    }
    res_aiptw <- rbind(res_aiptw, simr_aiptw)
    i <- i+1
  }  
  
  
  ### G-computation / Standardisation
  
  # Same relationship in each group
  res_gcomp <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running G-computation function
    temp <- try(fgcomp(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_gcomp  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_gcomp  <- data.frame(outcome=i,  
                                gcomp_diff=9999, gcomp_se=9999, gcomp_cl=9999, 
                                gcomp_cu=9999, gcomp_p=9999)
    }
    res_gcomp <- rbind(res_gcomp, simr_gcomp)
    i <- i+1
  }  
  
  # Differing relationships by group
  res_gcomp_int <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running G-computation function
    temp <- try(fgcomp_int(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_gcomp_int  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_gcomp_int  <- data.frame(outcome=i,  
                                    gcomp_int_diff=9999, gcomp_int_se=9999, gcomp_int_cl=9999, 
                                    gcomp_int_cu=9999, gcomp_int_p=9999)
    }
    res_gcomp_int <- rbind(res_gcomp_int, simr_gcomp_int)
    i <- i+1
  }  
  
  
  
  # Differing relationships by group with spline 
  res_gcomp_int_spline <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running G-computation function
    temp <- try(fgcomp_int_spline(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_gcomp_int  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_gcomp_int  <- data.frame(outcome=i,  
                                    gcomp_int_diff=9999, gcomp_int_se=9999, gcomp_int_cl=9999, 
                                    gcomp_int_cu=9999, gcomp_int_p=9999)
    }
    res_gcomp_int_spline <- rbind(res_gcomp_int_spline, simr_gcomp_int)
    i <- i+1
  }  
  
  
  ### TMLE
  
  # Without superlearner
  res_tmle <- NULL
  
  i <- 1
  for (var in ylist) {
    
    # Try running TMLE function
    temp <- try(ftmle(data, var, "treat", "x", "No"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_tmle  <- cbind(outcome=i,  as.data.frame(temp))
    } else {
      simr_tmle  <- data.frame(outcome=i,  
                               tmle_diff=9999, tmle_se=9999, tmle_cl=9999, 
                               tmle_cu=9999, tmle_p=9999)
    }
    res_tmle <- rbind(res_tmle, simr_tmle)
    i <- i+1
  }  
  
  
  ### CBPS
  
  res_cbps <- NULL
  i <- 1
  for (var in ylist) {
    
    # Try running CBPS function
    temp <- try(fcbps(data, var, "treat", "x"), TRUE)
    
    # If converges, save output; otherwise substitute 9999s
    if(is.list(temp)) {
      simr_cbps  <- cbind(outcome=i, as.data.frame(temp))
    } else {
      simr_cbps  <- data.frame(outcome=i, 
                               cbps_diff=9999, cbps_se=9999, cbps_cl=9999, 
                               cbps_cu=9999, cbps_p=9999)
    }
    res_cbps <- rbind(res_cbps, simr_cbps)
    i <- i+1
  }  
  
  
  
  
  ### Tidy and return results  ###
  
  # Combine results from different analysis methods
  results <- cbind(res_ttest, res_ancova[,2:6], res_spline4[,2:6],  res_spline20[,2:6], res_correct[,2:6], 
                   res_iptw[,2:6], res_iptw_spline[,2:6], res_aiptw[,2:6], res_gcomp[,2:6], res_gcomp_int[,2:6], 
                   res_gcomp_int_spline[,2:6], res_tmle[,2:6], res_cbps[,2:6])
  
  # Return results
  return(results)
}

# Simulate multiple datasets-------------------------------
sim_cts_normal <- function(iter, n, sd=42, true_diff=40, seed){
  # Arguments: iter=# iterations; n=sample size; seed=random seed)

  # Set the seed for reproducibility
  set.seed(seed)
  
  # Null matrix for initial simulation results
  res_sim<-NULL
  
  # Perform "iter" simulations
  for(i in 1:iter){
    print(i)
    simr    <- callfun_cts_normal(n, sd, true_diff)
    res_sim <- rbind(res_sim, simr)
  }
  
  # Add columns for sample size, sd and true treatment effect
  res_sim <- cbind(n=n, sd=sd, true_diff=true_diff, res_sim) 
  
  return(res_sim)
}

# Loop over four sample sizes, error variances, and true effect sizes        
for (n in c(100)) {
  for (s in c(42, 100)) {
    for (d in c(40, 0)) {
      
      # Run function sim to obtain simulation results:
      res <- sim_cts_normal(1000, n, s, d, 2348) 
      
      # Export simulated results to a CSV file  
      write.csv(res,paste0(path_stub_out, n, "_", s, "_", d , "extra.csv"))
    }
  }
}


#----------------------------------------------------------
#Extention 1: Multiple covariates
#----------------------------------------------------------

#  Simulate and analyse one dataset -----------------------

callfun_multiple <- function(n, treat_effect){
  
  ### Simulate a single dataset
  data <- gen_multiple(n, treat_effect)
  
  
  ### Analyse  ###
  
  # List of outcomes
  ylist <- c("cts_y1", "cts_y2", "cts_y3")
  
  # List of potential baseline covariates
  covlist1 <- "c1 + c4 + c16"
  if (n>49) {
    covlist2 <- "c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 + c10 + c11 + c12 + c13 + c14 + c15 + c16 + c17"
    covlist3 <- "c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 + c10 + c11 + c12 + c13 + c14 + c15 + c16 + c17 + c18 + c19 + c20 + c21"
    covlist <- c(covlist1, covlist2, covlist3)
  } else {
    covlist <- c(covlist1)
  }
  
  # For TMLE
  covlist1_tmle <- c("c1", "c4", "c16")
  covlist2_tmle <- c("c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17")
  covlist3_tmle <- c("c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21")
  
  
  ### T-test
  
  res_ttest <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running regression function
      temp <- try(fttest(data, var, "treat"), TRUE)
      
      if(is.list(temp)) {
        simr_ttest  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_ttest  <- data.frame(outcome=i,  covariate_set=k, 
                                  ttest_diff=9999, ttest_se=9999, ttest_cl=9999, 
                                  ttest_cu=9999, ttest_p=9999)
      }
      res_ttest <- rbind(res_ttest, simr_ttest)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  ### Multiple linear regression
  
  res_ancova <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running regression function
      temp <- try(fancova(data, var, "treat", cov), TRUE)
      
      if(is.list(temp)) {
        simr_ancova  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_ancova  <- data.frame(outcome=i,  covariate_set=k, 
                                   ancova_diff=9999, ancova_se=9999, ancova_cl=9999, 
                                   ancova_cu=9999, ancova_p=9999)
      }
      res_ancova <- rbind(res_ancova, simr_ancova)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  ### IPTW
  
  res_iptw <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running IPTW function
      temp <- try(fiptw(data, var, "treat", cov), TRUE)
      
      if(is.list(temp)) {
        simr_iptw  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_iptw  <- data.frame(outcome=i,  covariate_set=k, 
                                 iptw_diff=9999, iptw_se=9999, iptw_cl=9999, 
                                 iptw_cu=9999, iptw_p=9999, 
                                 w_min=9999, w_1q=9999, w_median=9999,
                                 w_mean=9999, w_3q=9999, w_max=9999)
      }
      res_iptw <- rbind(res_iptw, simr_iptw)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  ### AIPTW
  
  res_aiptw <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running AIPTW function
      temp <- try(faiptw(data, var, "treat", cov), TRUE)
      
      if(is.list(temp)) {
        simr_aiptw  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_aiptw  <- data.frame(outcome=i,  covariate_set=k, 
                                  aiptw_diff=9999, aiptw_se=9999, aiptw_cl=9999, 
                                  aiptw_cu=9999, aiptw_p=9999)
      }
      res_aiptw <- rbind(res_aiptw, simr_aiptw)
      k <- k+1
    }
    i <- i+1
  }  
  
  
  
  ### G-computation / Standardisation
  
  # Same model in each arm
  res_gcomp <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running G-computation function
      temp <- try(fgcomp(data, var, "treat", cov), TRUE)
      
      if(is.list(temp)) {
        simr_gcomp  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_gcomp  <- data.frame(outcome=i,  covariate_set=k, 
                                  gcomp_diff=9999, gcomp_se=9999, gcomp_cl=9999, 
                                  gcomp_cu=9999, gcomp_p=9999)
      }
      res_gcomp <- rbind(res_gcomp, simr_gcomp)
      k <- k+1
    }
    i <- i+1
  }  
  
  
  # Different models in each arm
  res_gcomp_int <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running G-computation function
      temp <- try(fgcomp_int(data, var, "treat", cov), TRUE)
      
      if(is.list(temp)) {
        simr_gcomp_int  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_gcomp_int  <- data.frame(outcome=i,  covariate_set=k, 
                                      gcomp_int_diff=9999, gcomp_int_se=9999, gcomp_int_cl=9999, 
                                      gcomp_int_cu=9999, gcomp_int_p=9999)
      }
      res_gcomp_int <- rbind(res_gcomp_int, simr_gcomp_int)
      k <- k+1
    }
    i <- i+1
  }  
  
  
  
  ### TMLE
  
  res_tmle <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running TMLE function
      if (k==1  & n>49) {
        temp <- try(ftmle_mult(data, var, "treat", covlist1_tmle, "No"), TRUE)
      } else if (k==2 & n>49) {
        temp <- try(ftmle_mult(data, var, "treat", covlist2_tmle, "No"), TRUE)
      } else if (k==3 & n>49) {
        temp <- try(ftmle_mult(data, var, "treat", covlist3_tmle, "No"), TRUE)
      }
      
      # If converges save estiamtes; otherwise replace with 9999s
      if(is.list(temp) & n>49) {
        simr_tmle  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_tmle  <- data.frame(outcome=i,  covariate_set=k, 
                                 tmle_diff=9999, tmle_se=9999, tmle_cl=9999, 
                                 tmle_cu=9999, tmle_p=9999)
      }
      res_tmle <- rbind(res_tmle, simr_tmle)
      k <- k+1
    }
    i <- i+1
  }  
  
  
  
  ### CBPS
  
  res_cbps <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running CBPS function
      temp <- try(fcbps(data, var, "treat", cov), TRUE)
      
      if(is.list(temp)) {
        simr_cbps  <- cbind(outcome=i,  covariate_set=k, as.data.frame(temp))
      } else {
        simr_cbps  <- data.frame(outcome=i,  covariate_set=k, 
                                 cbps_diff=9999, cbps_se=9999, cbps_cl=9999, 
                                 cbps_cu=9999, cbps_p=9999)
      }
      res_cbps <- rbind(res_cbps, simr_cbps)
      k <- k+1
    }
    i <- i+1
  }  
  
  
  
  
  ### Tidy and return results  ###
  
  # Combine results from different analysis methods
  results <- cbind(res_ttest, res_ancova[,3:7], res_iptw[,3:13], res_aiptw[,3:7], 
                   res_gcomp[,3:7], res_gcomp_int[,3:7], res_tmle[,3:7], res_cbps[,3:7])
  # Return results
  return(results)
}

# Simulate multiple datasets ------------------------------ 
sim_multiple <- function(iter, n, seed, treat_effect){
  # Arguments: iter=# iterations; n=sample size; seed=random seed)
  
  # Set the seed for reproducibility
  set.seed(seed)
  
  # Null matrix for initial simulation results
  res_sim<-NULL
  
  # Perform "iter" simulations
  for(i in 1:iter){
    print(i)
    simr    <- callfun_multiple(n, treat_effect)
    res_sim <- rbind(res_sim, simr)
  }
  
  # Add columns for sample size, sd and true treatment effect
  res_sim <- cbind(n=n, res_sim) 
  
  return(res_sim)
}

# Loop over four sample sizes and true effect sizes        
for (n in c(25, 50, 100, 250)) {
  for (t in c(TRUE, FALSE)) {

    # Run function sim to obtain simulation results:
    res <- sim_multiple(1000, n,  2348, t) 
    
    # Export simulated results to a CSV file  
    write.csv(res,paste0(path_stub_out, n, "_", t, ".csv"))
    
  }
}

#----------------------------------------------------------
#Extension 2: Interactions 
#----------------------------------------------------------

#Simulate and analyse one dataset--------------------------
callfun_cts_inter <- function(n){
  
  
  ### Simulate a single dataset
  data <- gen_cts_inter(n)
  
  
  ### Analyse  ###
  
  # Null matrix to put results in
  res_all <- NULL
  
  # Loop over outcomes and covariates
  for (j in 1:4) {
    
    if (j==1) {
      ylist <- c("y1")
      covlist <- c("x")
    } else if (j==2) {
      ylist <- c("y2")
      covlist <- c("x")      
    } else if (j==3) {
      ylist <- c("y3")
      covlist <- c("x")      
    } else if (j==4) {
      ylist <- c("y4")
      covlist <- c("c")      
    }      
    
    
    ### T-test
    
    res_ttest <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        simr      <- cbind(outcome=i, covariate=k, fttest(data, var, "treat"))
        res_ttest <- rbind(res_ttest, simr)
        k <- k+1
      }
      i <- i+1
    }
    
    
    
    ### ANCOVA
    
    res_ancova <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        simr       <- cbind(outcome=i,  covariate=k, fancova(data, var, "treat", cov))
        res_ancova <- rbind(res_ancova, simr)
        k <- k+1
      }
      i <- i+1
    }
    
    
    ### Splines
    
    # DF - 4
    res_spline4 <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        simr       <- cbind(outcome=i,  covariate=k, fspline(data, var, "treat", cov, 4))
        res_spline4 <- rbind(res_spline4, simr)
        k <- k+1
      }
      i <- i+1
    }
    
    
    ### IPTW
    
    res_iptw <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        simr       <- cbind(outcome=i,  covariate=k, fiptw(data, var, "treat", cov))
        res_iptw <- rbind(res_iptw, simr)
        k <- k+1
      }
      i <- i+1
    }
    
    
    ### AIPTW
    
    res_aiptw <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        simr       <- cbind(outcome=i,  covariate=k, faiptw(data, var, "treat", cov))
        res_aiptw <- rbind(res_aiptw, simr)
        k <- k+1
      }
      i <- i+1
    }  
    
    
    ### G-computation / Standardisation
    
    # Same relationship in both arms
    res_gcomp <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        
        # Try running G-computation function
        temp <- try(fgcomp(data, var, "treat", cov), TRUE)
        
        if(is.list(temp)) {
          simr_gcomp  <- cbind(outcome=i,  covariate=k, as.data.frame(temp))
        } else {
          simr_gcomp  <- data.frame(outcome=i,  covariate=k, 
                                    gcomp_diff=9999, gcomp_se=9999, gcomp_cl=9999, 
                                    gcomp_cu=9999, gcomp_p=9999)
        }
        res_gcomp <- rbind(res_gcomp, simr_gcomp)
        k <- k+1
      }
      i <- i+1
    }  
    
    
    # Differing relationships in the two arms
    res_gcomp_int <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        
        # Try running G-computation function
        temp <- try(fgcomp_int(data, var, "treat", cov), TRUE)
        
        if(is.list(temp)) {
          simr_gcomp_int  <- cbind(outcome=i,  covariate=k, as.data.frame(temp))
        } else {
          simr_gcomp_int  <- data.frame(outcome=i,  covariate=k, 
                                        gcomp_int_diff=9999, gcomp_int_se=9999, gcomp_int_cl=9999, 
                                        gcomp_int_cu=9999, gcomp_int_p=9999)
        }
        res_gcomp_int <- rbind(res_gcomp_int, simr_gcomp_int)
        k <- k+1
      }
      i <- i+1
    }  
    
    
    ### TMLE
    
    res_tmle <- NULL
    
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        
        # Try running TMLE function
        temp <- try(ftmle(data, var, "treat", cov, "No"), TRUE)
        
        if(is.list(temp)) {
          simr_tmle  <- cbind(outcome=i,  covariate=k, as.data.frame(temp))
        } else {
          simr_tmle  <- data.frame(outcome=i,  covariate=k, 
                                   tmle_diff=9999, tmle_se=9999, tmle_cl=9999, 
                                   tmle_cu=9999, tmle_p=9999)
        }
        res_tmle <- rbind(res_tmle, simr_tmle)
        k <- k+1
      }
      i <- i+1
    }  
    
    
    ### CBPS
    
    res_cbps <- NULL
    i <- 1
    for (var in ylist) {
      k <- 1
      for (cov in covlist) {
        
        # Try running CBPS function
        temp <- try(fcbps(data, var, "treat", cov), TRUE)
        
        if(is.list(temp)) {
          simr_cbps  <- cbind(outcome=i,  covariate=k, as.data.frame(temp))
        } else {
          simr_cbps  <- data.frame(outcome=i,  covariate=k, 
                                   cbps_diff=9999, cbps_se=9999, cbps_cl=9999, 
                                   cbps_cu=9999, cbps_p=9999)
        }
        res_cbps <- rbind(res_cbps, simr_cbps)
        k <- k+1
      }
      i <- i+1
    }  
    
    
    
    ### Tidy and return results  ###
    
    # Combine results from different analysis methods
    results <- cbind(outcome = j, res_ttest, res_ancova[,3:7], res_spline4[,3:7],  
                     res_iptw[,3:7], res_aiptw[,3:7], res_gcomp[,3:7], res_gcomp_int[,3:7],res_tmle[,3:7], res_cbps[,3:7])
    
    res_all <- rbind(res_all, results)
  }
  
  
  # Return results
  return(res_all)
}

#Simulate multiple datasets--------------------------------
sim_cts_inter <- function(iter, n, seed){
  # Arguments: iter=# iterations; n=sample size; seed=random seed)
  
  # Set the seed for reproducibility
  set.seed(seed)
  
  # Null matrix for initial simulation results
  res_sim<-NULL
  
  # Perform "iter" simulations
  for(i in 1:iter){
    print(i)
    simr    <- callfun_cts_inter(n)
    res_sim <- rbind(res_sim, simr)
  }
  
  # Add columns for sample size, sd and true treatment effect
  res_sim <- cbind(n=n, res_sim) 
  
  return(res_sim)
}

# Loop over sample sizes      
for (n in c(25, 50, 100, 250)) {
  
  # Run function sim to obtain simulation results:
  res <- sim_cts_inter(1000, n, 2348) 
  
  # Export simulated results to a CSV file  
  write.csv(res,paste0(path_stub_out, n, ".csv"))
}


#----------------------------------------------------------
#Extension 3: Binary Outcomes 
#----------------------------------------------------------

#Simulate and analyse one dataset--------------------------
callfun <- function(n, true_or=0.46){
  
  
  ### Simulate a single dataset
  data <- generate_bin_strong_normal(n, true_or)
  
  ### Analyse  ###
  
  # List of outcomes
  ylist <- c("y1", "y2", "y3", "y4", "y5", "y6", "y7")
  
  # List of potential baseline covariates
  covlist <- c("x")
  
  
  ### Unadjusted
  
  lnor_res_unadj <- NULL
  #   lnrr_res_unadj <- NULL
  rd_res_unadj <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      lnor_simr  <- cbind(outcome=i, cov=k, f_or(data, var, "treat"))
      #      lnrr_simr  <- cbind(outcome=i, cov=k, f_rr(data, var, "treat"))
      rd_simr    <- cbind(outcome=i, cov=k, f_rd(data, var, "treat"))
      lnor_res_unadj <- rbind(lnor_res_unadj, lnor_simr)
      #      lnrr_res_unadj <- rbind(lnrr_res_unadj, lnrr_simr)
      rd_res_unadj <- rbind(rd_res_unadj, rd_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  ### Adjusted regression
  
  lnor_res_adj <- NULL
  # lnrr_res_adj <- NULL
  #lnrr_res_adj2 <- NULL
  rd_res_adj <- NULL
  
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running adjusted regression models
      temp_lnor <- try(f_aor(data, var, "treat", cov), TRUE)
      #  temp_lnrr <- try(f_arr(data, var, "treat", cov), TRUE)
      #  temp_lnrr2 <- try(f_arr2(data, var, "treat", cov), TRUE)
      temp_rd <- try(f_ard(data, var, "treat", cov), TRUE)
      
      if(is.list(temp_lnor)) {
        lnor_adj_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor))
      } else {
        lnor_adj_simr  <- data.frame(outcome=i,  cov=k, 
                                     lnor_radj_diff=9999, lnor_radj_se=9999, lnor_radj_cl=9999, 
                                     lnor_radj_cu=9999, lnor_radj_p=9999, scale="log")
      }
      # if(is.list(temp_lnrr)) {
      #    lnrr_adj_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnrr))
      #  } else {
      #    lnrr_adj_simr  <- data.frame(outcome=i,  cov=k, 
      #                             lnrr_radj_diff=9999, lnrr_radj_se=9999, lnrr_radj_cl=9999, 
      #                             lnrr_radj_cu=9999, lnrr_radj_p=9999, scale="log")
      #  }     
      #  if(is.list(temp_lnrr2)) {
      #    lnrr_adj_simr2  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnrr2))
      #  } else {
      #    lnrr_adj_simr2  <- data.frame(outcome=i,  cov=k, 
      #                             lnrr_radj2_diff=9999, lnrr_radj2_se=9999, lnrr_radj2_cl=9999, 
      #                             lnrr_radj2_cu=9999, lnrr_radj2_p=9999, scale="log")
      #  }
      if(is.list(temp_rd)) {
        rd_adj_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_rd))
      } else {
        rd_adj_simr  <- data.frame(outcome=i,  cov=k, 
                                   rd_radj_diff=9999, rd_radj_se=9999, rd_radj_cl=9999, 
                                   rd_radj_cu=9999, rd_radj_p=9999, scale="unlog")
      }        
      
      lnor_res_adj <- rbind(lnor_res_adj, lnor_adj_simr)
      # lnrr_res_adj <- rbind(lnrr_res_adj, lnrr_adj_simr)
      #  lnrr_res_adj2 <- rbind(lnrr_res_adj2, lnrr_adj_simr2)
      rd_res_adj <- rbind(rd_res_adj, rd_adj_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  
  ## adjusted regression with firth correction 
  
  lnor_res_adj_firth <- NULL
  
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running adjusted regression models
      temp_lnor_firth <- try(f_aor_firth(data, var, "treat", cov), TRUE)
      
      
      if(!is.null(temp_lnor_firth)) {
        lnor_adj_firth_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor_firth))
      } else {
        lnor_adj_firth_simr  <- data.frame(outcome=i,  cov=k, 
                                           lnor_radj_firth_diff=9999, lnor_radj_firth_se=9999, lnor_radj_firth_cl=9999, 
                                           lnor_radj_firth_cu=9999, lnor_radj_firth_p=9999, scale="log")
      }
      
      lnor_res_adj_firth <- rbind(lnor_res_adj_firth, lnor_adj_firth_simr)
      
      k <- k+1
    }
    i <- i+1
  }
  
  
  ### Splines
  
  # DF - 4
  lnor_res_spline4 <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running adjusted regression models
      temp_lnor_spl <- try(f_or_spline(data, var, "treat", cov, 4), TRUE)
      
      if(is.list(temp_lnor_spl)) {
        lnor_spline4_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor_spl))
      } else {
        lnor_spline4_simr  <- data.frame(outcome=i,  cov=k, 
                                         lnor_spline_diff=9999, lnor_spline_se=9999, lnor_spline_cl=9999, 
                                         lnor_spline_cu=9999, lnor_spline_p=9999, scale="log")
      }
      
      lnor_res_spline4 <- rbind(lnor_res_spline4, lnor_spline4_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  # DF - 20
  lnor_res_spline20 <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running adjusted regression models
      temp_lnor_spl <- try(f_or_spline(data, var, "treat", cov, 20), TRUE)
      
      if(!is.null(temp_lnor_spl)) {
        lnor_spline20_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor_spl))
      } else {
        lnor_spline20_simr  <- data.frame(outcome=i,  cov=k, 
                                          lnor_spline_diff=9999, lnor_spline_se=9999, lnor_spline_cl=9999, 
                                          lnor_spline_cu=9999, lnor_spline_p=9999, scale="log")
      }
      
      lnor_res_spline20 <- rbind(lnor_res_spline20, lnor_spline20_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  #splines with firth correction 
  #DF-4
  lnor_res_spline4_firth <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running adjusted regression models
      temp_lnor_spl <- try(f_or_spline_firth(data, var, "treat", cov, 4), TRUE)
      
      if(!is.null(temp_lnor_spl)) {
        lnor_spline4_firth_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor_spl))
      } else {
        lnor_spline4_firth_simr  <- data.frame(outcome=i,  cov=k, 
                                               lnor_spline_firth_diff=9999, lnor_spline_firth_se=9999, lnor_spline_firth_cl=9999, 
                                               lnor_spline_firth_cu=9999, lnor_spline_firth_p=9999, scale="log")
      }
      
      lnor_res_spline4_firth <- rbind(lnor_res_spline4_firth, lnor_spline4_firth_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  #DF-20
  
  lnor_res_spline20_firth <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running adjusted regression models
      temp_lnor_spl <- try(f_or_spline_firth(data, var, "treat", cov, 20), TRUE)
      
      if(is.list(temp_lnor_spl)) {
        lnor_spline20_firth_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor_spl))
      } else {
        lnor_spline20_firth_simr  <- data.frame(outcome=i,  cov=k, 
                                                lnor_spline_firth_diff=9999, lnor_spline_firth_se=9999, lnor_spline_firth_cl=9999, 
                                                lnor_spline_firth_cu=9999, lnor_spline_firth_p=9999, scale="log")
      }
      
      lnor_res_spline20_firth <- rbind(lnor_res_spline20_firth, lnor_spline20_firth_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  
  ### Correct model
  
  #    lnor_res_correct <- NULL
  #    i <- 1
  #    for (var in ylist) {
  #      k <- 1
  #      for (cov in covlist) {
  
  # Try running correct regression models
  #        temp_lnor_cor <- try(f_or_correct(data, var, "treat", cov), TRUE)
  
  #        if(is.list(temp_lnor_cor)) {
  #          lnor_corr_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_lnor_cor))
  #        }  else {
  #          lnor_corr_simr  <- data.frame(outcome=i,  cov=k, 
  #                                          lnor_correct_diff=9999, lnor_correct_se=9999, lnor_correct_cl=9999, 
  #                                           lnor_correct_cu=9999, lnor_correct_p=9999, scale="log")
  #       }
  #        simr       <- cbind(outcome=i,  covariate=k, f_or_correct(data, var, "treat", cov))
  #        lnor_res_correct <- rbind(lnor_res_correct, lnor_corr_simr)
  #        k <- k+1
  #      }
  #      i <- i+1
  #    }
  
  
  
  ### IPTW
  
  lnor_res_iptw <- NULL
  #   lnrr_res_iptw <- NULL
  rd_res_iptw <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running model
      temp_iptw <- try(f_bin_iptw(data, var, "treat", cov), TRUE)
      
      if(is.list(temp_iptw)) {
        lnor_iptw_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_iptw[[1]]))
        #         lnrr_iptw_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_iptw[[2]]))
        rd_iptw_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_iptw[[3]]))
      } else {
        lnor_iptw_simr  <- data.frame(outcome=i,  cov=k, 
                                      lnor_iptw_diff=9999, lnor_iptw_se=9999, lnor_iptw_cl=9999, 
                                      lnor_iptw_cu=9999, lnor_iptw_p=9999, scale="log")
        #          lnrr_iptw_simr  <- data.frame(outcome=i,  cov=k, 
        #                                        lnrr_iptw_diff=9999, lnrr_iptw_se=9999, lnrr_iptw_cl=9999, 
        #                                        lnrr_iptw_cu=9999, lnrr_iptw_p=9999, scale="log")
        rd_iptw_simr  <- data.frame(outcome=i,  cov=k, 
                                    rd_iptw_diff=9999, rd_iptw_se=9999, rd_iptw_cl=9999, 
                                    rd_iptw_cu=9999, rd_iptw_p=9999, scale="unlog")       
      }
      lnor_res_iptw <- rbind(lnor_res_iptw, lnor_iptw_simr)
      #       lnrr_res_iptw <- rbind(lnrr_res_iptw, lnrr_iptw_simr)
      rd_res_iptw <- rbind(rd_res_iptw, rd_iptw_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  ### AIPTW
  
  rd_res_aiptw <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running model
      temp_aiptw <- try(f_rd_aiptw(data, var, "treat", cov), TRUE)
      
      
      if(is.list(temp_aiptw)) {
        rd_aiptw_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_aiptw))
      } else {
        rd_aiptw_simr  <- data.frame(outcome=i,  cov=k, 
                                     rd_aiptw_diff=9999, rd_aiptw_se=9999, rd_aiptw_cl=9999, 
                                     rd_aiptw_cu=9999, rd_aiptw_p=9999, scale="unlog")       
      }
      rd_res_aiptw <- rbind(rd_res_aiptw, rd_aiptw_simr)
      k <- k+1
    }
    i <- i+1
  }  
  
  
  
  
  ### G-computation / Standardisation
  
  
  
  lnor_res_gcomp <- NULL
  #  lnrr_res_gcomp <- NULL
  rd_res_gcomp <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running model
      temp_gcomp <- try(f_bin_gcomp(data, var, "treat", cov), TRUE)
      
      if(is.list(temp_gcomp)) {
        lnor_gcomp_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_gcomp[[1]]))
        #       lnrr_gcomp_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_gcomp[[2]]))
        rd_gcomp_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_gcomp[[3]]))
      } else {
        lnor_gcomp_simr  <- data.frame(outcome=i,  cov=k, 
                                       lnor_gcomp_diff=9999, lnor_gcomp_se=9999, lnor_gcomp_cl=9999, 
                                       lnor_gcomp_cu=9999, lnor_gcomp_p=9999, scale="log")
        #        lnrr_gcomp_simr  <- data.frame(outcome=i,  cov=k, 
        #                                      lnrr_gcomp_diff=9999, lnrr_gcomp_se=9999, lnrr_gcomp_cl=9999, 
        #                                      lnrr_gcomp_cu=9999, lnrr_gcomp_p=9999, scale="log")
        rd_gcomp_simr  <- data.frame(outcome=i,  cov=k, 
                                     rd_gcomp_diff=9999, rd_gcomp_se=9999, rd_gcomp_cl=9999, 
                                     rd_gcomp_cu=9999, rd_gcomp_p=9999, scale="unlog")       
      }
      lnor_res_gcomp <- rbind(lnor_res_gcomp, lnor_gcomp_simr)
      #     lnrr_res_gcomp <- rbind(lnrr_res_gcomp, lnrr_gcomp_simr)
      rd_res_gcomp <- rbind(rd_res_gcomp, rd_gcomp_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  ### TMLE
  
  lnor_res_tmle <- NULL
  #  lnrr_res_tmle <- NULL
  rd_res_tmle <- NULL
  i <- 1
  for (var in ylist) {
    k <- 1
    for (cov in covlist) {
      
      # Try running model
      temp_tmle <- try(f_bin_tmle(data, var, "treat", cov), TRUE)
      
      if(is.list(temp_tmle)) {
        lnor_tmle_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_tmle[[1]]))
        #       lnrr_tmle_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_tmle[[2]]))
        rd_tmle_simr  <- cbind(outcome=i, cov=k, as.data.frame(temp_tmle[[3]]))
      } else {
        lnor_tmle_simr  <- data.frame(outcome=i,  cov=k, 
                                      lnor_tmle_diff=9999, lnor_tmle_se=9999, lnor_tmle_cl=9999, 
                                      lnor_tmle_cu=9999, lnor_tmle_p=9999, scale="log")
        #        lnrr_tmle_simr  <- data.frame(outcome=i,  cov=k, 
        #                                       lnrr_tmle_diff=9999, lnrr_tmle_se=9999, lnrr_tmle_cl=9999, 
        #                                       lnrr_tmle_cu=9999, lnrr_tmle_p=9999, scale="log")
        rd_tmle_simr  <- data.frame(outcome=i,  cov=k, 
                                    rd_tmle_diff=9999, rd_tmle_se=9999, rd_tmle_cl=9999, 
                                    rd_tmle_cu=9999, rd_tmle_p=9999, scale="unlog")       
      }
      lnor_res_tmle <- rbind(lnor_res_tmle, lnor_tmle_simr)
      #      lnrr_res_tmle <- rbind(lnrr_res_tmle, lnrr_tmle_simr)
      rd_res_tmle <- rbind(rd_res_tmle, rd_tmle_simr)
      k <- k+1
    }
    i <- i+1
  }
  
  
  
  
  
  ### Tidy and return results  ###
  
  # Combine results from different analysis methods
  lnor_results <- cbind(lnor_res_unadj, lnor_res_adj[,3:7], lnor_res_adj_firth[,3:7], 
                        lnor_res_spline4[,3:7],  lnor_res_spline20[,3:7], 
                        lnor_res_spline4_firth[,3:7], lnor_res_spline20_firth[,3:7], 
                        #lnor_res_correct[,3:7], 
                        lnor_res_iptw[,3:7], lnor_res_gcomp[,3:7], lnor_res_tmle[,3:7])
  #   lnrr_results <- cbind(lnrr_res_unadj, lnrr_res_adj[,3:7], lnrr_res_adj2[,3:7], lnrr_res_iptw[,3:7], lnrr_res_gcomp[,3:7], lnrr_res_tmle[,3:7])
  rd_results <- cbind(rd_res_unadj, rd_res_adj[,3:7], rd_res_iptw[,3:7], rd_res_aiptw[,3:7], rd_res_gcomp[,3:7], rd_res_tmle[,3:7])
  
  return(list(lnor_results, #lnrr_results, 
              rd_results))
  
  
}

#Simulate multiple datasets--------------------------------
sim <- function(iter, n, true_or=0.46, seed){
  # Arguments: iter=# iterations; n=sample size; seed=random seed)

  # Set the seed for reproducibility
  set.seed(seed)
  
  # Null matrix for initial simulation results
  lnor_res_sim<-NULL
  #lnrr_res_sim<-NULL
  rd_res_sim<-NULL
  
  # Perform "iter" simulations
  for(i in 1:iter){
    print(i)
    simr    <- callfun(n, true_or)
    lnor_simr    <- simr[[1]]
    #  lnrr_simr    <- simr[[2]]
    rd_simr    <- simr[[2]]
    lnor_res_sim <- rbind(lnor_res_sim, lnor_simr)
    #   lnrr_res_sim <- rbind(lnrr_res_sim, lnrr_simr)
    rd_res_sim <- rbind(rd_res_sim, rd_simr)
  }
  
  # Add columns for sample size, sd and true treatment effect
  lnor_res_sim <- cbind(n=n, true_or=true_or, lnor_res_sim) 
  #   lnrr_res_sim <- cbind(n=n, true_or=true_or, lnrr_res_sim) 
  rd_res_sim <- cbind(n=n, true_or=true_or, rd_res_sim) 
  
  return(list(lnor_res_sim, #lnrr_res_sim, 
              rd_res_sim))
}

# Loop over sample sizes and true effect sizes        
for (n in c(100)) {
  for (r in c(0.2, 1)) {
    
    # Run function sim to obtain simulation results:
    res <- sim(1000, n, r, 2348) 
    
    lnor_res <- res[[1]]
    rd_res <- res[[2]]
    
    # Export simulated results to a CSV file  
    write.csv(lnor_res,paste0(path_stub_out_lnor, n, "_", r, ".csv"))
    #write.csv(lnrr_res,paste0(path_stub_out_lnrr, n, "_", r, ".csv"))
    write.csv(rd_res,paste0(path_stub_out_rd, n, "_", r, ".csv"))
  }
}




