Project: s41467-025-57887-3 | Function: CCT (r)

system: You are an expert R programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow R best practices and maintain consistent code style.
Return **only** the complete R function code.

user: Complete this R function:

**DESCRIPTION:** Cauchy combination test for combining p-values with optional weights. Implements statistical method for meta-analysis of p-values using Cauchy distribution.

**KEY TERMS:** {
  "pvals": "p-values",
  "weights": "test weights",
  "cct.stat": "CCT statistic"
}

**CONTEXT CODE:** #'
#' # we recommand using column of 'p.value.spaGxE.CCT.Wald' to associate genotype with binary phenotypes
#' head(binary.res)
#'
#'
#'
#' # example 7  binary phenotype (genotype input using BGEN file format)
#' library(SPAGxECCT)
#' # Simulate phenotype and genotype
#' N = 10000
#'
#' # BGEN format for genotype data
#' GenoFile = system.file("", "GenoMat_SPAGxE.bgen", package = "SPAGxECCT")
#' GenoFileIndex = c(system.file("", "GenoMat_SPAGxE.bgen.bgi", package = "SPAGxECCT"),
#'                   system.file("", "GenoMat_SPAGxE.sample", package = "SPAGxECCT"))
#'
#' # phenotype data
#' Phen.mtx = data.frame(ID = paste0("IID-",1:N),
#'                       Y=rbinom(N,1,0.5),
#'                       Cov1=rnorm(N),
#'                       Cov2=rbinom(N,1,0.5),
#'                       E = rnorm(N))
#'
#' Cova.mtx = Phen.mtx[,c("Cov1","Cov2")]    # covariates dataframe excluding environmental factor E
#' E = Phen.mtx$E                            # environmental factor E
#'
#' # fit a genotype-independent model
#' R = SPA_G_Get_Resid("binary",
#'                     glm(formula = Y ~ Cov1+Cov2+E, data = Phen.mtx, family = "binomial"),
#'                     data=Phen.mtx,
#'                     pIDs=Phen.mtx$ID,
#'                     gIDs=paste0("IID-",1:N))
#'
#' # calculate p values
#' binary.res = SPAGxE_CCT(traits = "binary",                       # trait type
#'                         GenoFile = GenoFile,                     # a character of genotype file
#'                         GenoFileIndex = GenoFileIndex,           # additional index file(s) corresponding to GenoFile
#'                         R = R,                                   # residuals from genotype-independent model (null model in which marginal genetic effect and GxE effect are 0)
#'                         E = E,                                   # environmental factor
#'                         Phen.mtx = Phen.mtx,                     # phenotype dataframe
#'                         Cova.mtx = Cova.mtx)                     # a covariate matrix excluding the environmental factor E
#'
#' # we recommand using column of 'p.value.spaGxE.CCT.Wald' to associate genotype with binary phenotypes
#' head(binary.res)
#'
#'
#' @export
#' @import survival
#' @import GRAB

SPAGxE_CCT = function(traits="survival/binary/quantitative/categorical",
                      GenoFile = NULL,
                      GenoFileIndex = NULL,
                      control = list(AllMarkers = TRUE),
                      Geno.mtx = NULL,
                      R,
                      E,
                      Phen.mtx,
                      Cova.mtx,
                      epsilon = 0.001,
                      Cutoff = 2,
                      impute.method = "fixed",
                      missing.cutoff = 0.15,
                      min.maf = 0.001,
                      G.model = "Add")
{
  ## check input
  par.list = list(pwd=getwd(),
                  sessionInfo=sessionInfo(),
                  impute.method=impute.method,
                  missing.cutoff=missing.cutoff,
                  min.maf=min.maf,
                  G.model=G.model)


  # update on 2024-12
  # suppressPackageStartupMessages(library("GRAB",quietly = T))

  if(is.null(Geno.mtx)){
    Geno.mtx = GRAB::GRAB.ReadGeno(GenoFile = GenoFile,
                                   GenoFileIndex = GenoFileIndex,
                                   SampleIDs = Phen.mtx$ID,
                                   control = control)$GenoMat
  }



  check_input_Resid(pIDs = Phen.mtx$ID, gIDs = rownames(Geno.mtx), R = R)
  print(paste0("Sample size is ",nrow(Geno.mtx),"."))
  print(paste0("Number of variants is ",ncol(Geno.mtx),"."))

  ### Prepare the main output data frame
  n.Geno = ncol(Geno.mtx)
  output = matrix(NA, n.Geno, 10) # update on 2023-12-27
  colnames(output) = c("MAF","missing.rate",
                       "p.value.spaGxE","p.value.spaGxE.Wald","p.value.spaGxE.CCT.Wald","p.value.normGxE",
                       "p.value.betaG", "Stat.betaG","Var.betaG","z.betaG") # update on 2023-12-27
  rownames(output) = colnames(Geno.mtx)

  ## Start analysis
  print("Start Analyzing...")
  print(Sys.time())

  # Cycle for genotype matrix
  for(i in 1:n.Geno){
    g = Geno.mtx[,i]

    output.one.SNP = SPAGxE_CCT_one_SNP(traits=traits,
                                        g,                     # genotype vector
                                        R,                     # residuals from genotype-independent model (null model in which marginal genetic effect and GxE effect are 0)
                                        E,                     # environmental factor
                                        Phen.mtx,              # phenotype dataframe
                                        Cova.mtx,              # other covariates (such as age, sex, and top PCs) excluding E
                                        epsilon,               # a fixed value
                                        Cutoff,
                                        impute.method,
                                        missing.cutoff,
                                        min.maf,
                                        G.model)
    output[i,] = output.one.SNP
  }

  print("Analysis Complete.")
  print(Sys.time())
  return(output)
}




#' A scalable and accurate framework for large-scale genome-wide gene-environment interaction (GxE) analysis (One-SNP-version).
#'
#' One-SNP-version SPAGxE_CCT function. This function is to facilitate users that prefer reading and analyzing genotype line-by-line.
#' @param g a numeric genotype vector. Missing genotype should be coded as NA. Both hard-called and imputed genotype data are supported.
#' @param others the same as function SPAGxE_CCT(). NOTE that we do not check subject order in this one-snp-version !!!
#' @return the same as function SPAGxE_CCT().
#' @export

SPAGxE_CCT_one_SNP = function(traits="survival/binary/quantitative/categorical",
                              g,                     # genotype vector
                              R,                     # residuals from genotype-independent model (null model in which marginal genetic effect and GxE effect are 0)
                              E,                     # environmental factor
                              Phen.mtx,              # phenotype dataframe
                              Cova.mtx,              # other covariates (such as age, sex, and top PCs) excluding E
                              epsilon = 0.001,       # a fixed value
                              Cutoff = 2,
                              impute.method = "fixed",
                              missing.cutoff = 0.15,
                              min.maf = 0.001,
                              G.model = "Add")


Complete the function implementation replacing "stop("Not implemented")".