-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem with population cosinors #1
Comments
Hi, I'm experiencing the same issue as described above with the population mean cosinor function. I posted a query about it on Stack Overflow (https://stackoverflow.com/questions/77469061/how-to-carry-out-population-mean-cosinor-analysis-in-r-using-card-package). Using the as.data.frame(kfits) fix described above by DV solved that error message. However, I found the coefficients from the resulting population mean cosinor model with that altered code were the same as those in the normal cosinor model (i.e., they were wrong). I'm not particularly proficient in R or using GitHub. Will there be any future updates of the 'card' package with this issue resolved? Or could you suggest an alternative approach that might be used? Thanks! |
Hi @AlistairCarr - thanks for your comment. I actually had an issue with a CRAN check about x 1 year ago, and I had limited time and resources to fix it at the time. Let me take a look at this issue in the upcoming 2-3 weeks, and see if I can at least repair it at the developmental level. If I can, you should be able to install the package from github directly. If I don't think I can fix it for whatever reason, I'll let you know as well. |
@AlistairCarr could you help me by either sharing the code or the discrepancy you found? I'm brushing up on the internals of the software this week. When you say "they were wrong", do you mean that the program reported the population mean consinor as if it was an individual cosinor? Thanks for the clarification! |
Hi, thanks for getting back. And just to feedback it's a great package I've really enjoyed using it. Find it much more intuitive and flexible for graphing than alternative packages that can do cosinor analyses. The link to the stat exchange question has code for the problem I'm experiencing, which sounds the same as experienced by DV. The below code I hope explains what I mean by 'being wrong'. Compared with the example coefficient output for a 'normal' cosinor model (model 'm' in code below) and population mean cosinor model (model 'm_pop' in code below), as used in your vignette, when I incorporate DV's edit suggestion into the code for the 'cosinor_pop_impl' function, the resulting coefficients I get from that model ('m_pop2' in code below) are equal to those of the 'normal' cosinor model (model 'm') rather than the population mean cosinor model ('m_pop'). I hope that makes sense? Apologies if my coding vocabulary is not up to scratch - as I say don't really have much experience in R. ` rm(list = ls()) install.packages('card')library(card) twins <- card::twins model coefficient outputs using card package#Normal consinor model m <- cosinor(rDYX ~ hour, data = twins, tau = 24) summary(m) #Population cosinor model m_pop <- cosinor(rDYX ~ hour, data = twins, tau = c(24), population = "patid") summary(m_pop) ################## model coefficient output using edited 'card' code ############### #underlying 'card' code, edited with DV's suggestion to make kfits as.data.frame #DV's suggested fix was: fits <- data.frame(population = rep(names(as.data.frame(kfits)),sapply(as.data.frame(kfits), length)),yhat = unlist(kfits))Cosinor Implementation {{{ ====Single Component Cosinor Implementation#' @description Model fitting algorithm for cosinor. Results in output that define the new S3 class, as seen by the [hardhat::new_model], which generates the Parameters for normal equationsFormal equationy(t) = M + Acos(2pi*t/tau + phi)A = Amplitudephi = acrophase (measure of hte time of overall high values in cycle)M = MESORy(t) = M + betax + gammaz + error(t)beta = A*cos(phi)gamma = -A*sin(phi)x = cos(2pit/tau)z = sin(2pit/tau)Where N is number of observations iterated through by iRSS = sum[y - (M + betax + gammaz)]^2Normal equations (where M, beta, gamma are the coefficients to solve for)sum(y) = Mn + betasum(x) + gamma*sum(z)sum(yx) = Msum(x) + betasum(x^2) + gammasum(x*z)sum(yz) = Msum(z) + betasum(xz) + gamma*sum(z^2)Multiple components... is an extension of single componenty(t) = M + sum_j[ A_jcos(2pi*t/tau_j + phi_j)y(t) = M + sum_j[beta_j * x_j + gamma_j * z_j] + error(t)Number of parameters will be the number of tause.g. single component = 3 components, where 3 = 2p + 1 (p = 1 component)p <- length(tau) Single parametersy <- outcomes Normal equation for 3 componentsNormal equations (where M, beta, gamma are the coefficients to solve for)sum(y) = Mn + betasum(x) + gamma*sum(z)sum(yx) = Msum(x) + betasum(x^2) + gammasum(x*z)sum(yz) = Msum(z) + betasum(xz) + gamma*sum(z^2)d = Su (for single component, 3 equations with 3 unknowns)For multiple components, the matrix must be expandedNeed to create number of x values to match number of tausx1, x2, z1, z2 in this casefor (i in 1:p) { Creating a new dataframe with all variablesmodel <- data.frame(y, t, mget(paste0("x", 1:p)), mget(paste0("z", 1:p))) The formula, where the intercept will be the MESOR (not included)f <- stats::formula( Can create a model frame here using two approachesBase R and with hardhatm <- stats::model.frame(f, model) Solving for coefficientsSolve for coefficients, including amplitude and acrophasecoefs <- solve(t(xmat) %% xmat) %% t(xmat) %*% ymat for (i in 1:p) {
} coefs <- unlist(c(mesor = mesor, mget(paste0("amp", 1:p)), mget(paste0("phi", 1:p)), mget(paste0("beta", 1:p)), mget(paste0("gamma", 1:p)))) Predicted / outputy(t) = M + b1 * x1 + g1 * z1 + b2 * x2 + g2 * z2y(t) = M + amp1 * cos(2pit/tau1 + phi1) + amp2 * cos(2pit/tau2 + phi2)pars <- list() Model OutputModel coefficientscoef_names <- names(coefs) Fit and residualsfitted.values <- yhat List to returnlist(
) } Population Mean Cosinor Implementation#' @description Model fitting algorithm for population-mean cosinor. Uses the Population cosinor parameter setupPeriodp <- length(tau) # Number of parameters ... single cosinor ~ 2p + 1 = 3 Create data frame for split/apply approachdf <- na.omit(data.frame(predictors, outcomes, population)) Remove patients with only p observations (will cause a det ~ 0 error)counts <- by(df, df[, "population"], nrow) Message about population count removalif (length(lowCounts) != 0) { Population parametersk <- length(unique(df$population)) # Number of individuals Need to create number of x values to match number of tausx1, x2, z1, z2 in this casefor (i in 1:p) { Creating a new dataframe with all variablesmodel <- data.frame(y, t, mget(paste0("x", 1:p)), mget(paste0("z", 1:p)), population) Create matrix that we can apply cosinor to subgroupskCosinors <- with( CoefficientsFits of individual cosinorskfits <- sapply(kCosinors, stats::fitted) Matrix of coefficientstbl <- sapply(kCosinors, stats::coef, USE.NAMES = TRUE) Get mean for each parameter (mesor, beta, gamma), ignoring averaged amp/phicoefs <- colMeans(xmat, na.rm = TRUE) for (i in 1:p) {
} Model outputFitted valuesy(t) = M + Acos(2pi*t/tau + phi)Individual fitsOverall modelyhat <- fits$yhat List of values to return (must be same as cosinor_impl)list(
) } ##coefficient outputs of mean population cosinor modeul using above edited cosinor_pop_impl function m_pop2 <- cosinor_pop_impl(twins$hour, twins$rDYX, 24, "patid") #coefficients from cosinor_pop_impl function = coefficients of normal cosinor model (model m) rather than population cosinor model (model m_pop) m_pop$coefficients m$coefficients ` |
@AlistairCarr - I appreciate the thorough response. I'll take a look more closely and see if we can resolve this. I imagine that its an inappropriate data reference somewhere when passing the population dataset. When I started writing this I was not consistent with my non-standard evaluation. I think it'll be 1-2 weeks to get to a resolution at least on the development version. |
Thanks the update. Good luck! |
Development version of population cosinor is being developed:
@AlistairCarr - thanks for bring this all to my attention again. I expect a working version in the next 1-2 weeks. |
… class from sapply in the chain, which should now be resolved, however need to test coefficients in additional dataframes #1
Problem with population cosinors, reported by DV.
Just to report that I found the following error when running cosinor for
calculating a population mean cosinor
To my best knowledge, I gave the same format to my file and relevant
variables as the Twins example file has. Twins runs ok, but not my file.
Even if I didn't find the reason for this, I solved it by running
cosinor_pop_impl and declaring kfits as data frame.
Originally, it returned
After declaring kfits as data frame, it returns
Above documentation from message from DV. Code below is from DV as part of a MWE.
Code that would lead to this problem is below (generated by DV).
The text was updated successfully, but these errors were encountered: