rsquaredacademy / olsrr

Tools for developing OLS regression models
https://olsrr.rsquaredacademy.com/
Other
102 stars 22 forks source link

ols_correlations error #191

Closed ButlerMSDA closed 1 year ago

ButlerMSDA commented 2 years ago

Brief description of the problem When running this function - It produces an error

ols_correlations(model) Error in model.frame.default(formula = mdata[[1]] ~ ., data = dat, drop.unused.levels = TRUE) : 'data' must be a data.frame, environment, or list

Other functions in the library seem to work as expected, only this one objects to the model as created

# insert reprex here
SocComp <- c(8,8,9,10,10,11,11,12,14,16)
IQ <- c(80,80,91,82,106,117,124,98,89,110)
Pop <-  c(1,2,2,1,3,5,2,4,5,5)

df <- data.frame(SocComp,IQ,Pop)
model <- lm (SocComp ~ IQ + Pop, data=df)
library(olsrr)
ols_correlations(model)
aravindhebbali commented 2 years ago

Hi @ButlerMSDA ,

I am not getting any error when I run the code. Please let me know which version of olsrr you are using. You can check the version of the package using packageVersion("olsrr").

ButlerMSDA commented 2 years ago

Thank you for checking:

packageVersion("olsrr") [1] ‘0.5.3’

Bob

Robert J. Padgett, Ph. D. Professor of Psychology Butler University 4600 Sunset Ave. Indianapolis, IN 46208 (317) 940-9239


From: Aravind Hebbali @.> Sent: Friday, December 24, 2021 3:34 AM To: rsquaredacademy/olsrr @.> Cc: Padgett, Robert @.>; Mention @.> Subject: Re: [rsquaredacademy/olsrr] ols_correlations error (Issue #191)

Hi @ButlerMSDAhttps://urldefense.com/v3/__https://github.com/ButlerMSDA__;!!NuAq3lKL!7RRmYuoRb9eVgdUSrVaCOO-PzHqmpsASz8_hJWjZ23TVCU5ZQXTIzQVU3wR6NsR-MA$ ,

I am not getting any error when I run the code. Please let me know which version of olsrr you are using. You can check the version of the package using packageVersion("olsrr").

— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https://github.com/rsquaredacademy/olsrr/issues/191*issuecomment-1000723842__;Iw!!NuAq3lKL!7RRmYuoRb9eVgdUSrVaCOO-PzHqmpsASz8_hJWjZ23TVCU5ZQXTIzQVU3wRUn7Dr-A$, or unsubscribehttps://urldefense.com/v3/__https://github.com/notifications/unsubscribe-auth/AU2SRXL5CAZQZWRSHJSZTN3USQWCDANCNFSM5KVWFFIQ__;!!NuAq3lKL!7RRmYuoRb9eVgdUSrVaCOO-PzHqmpsASz8_hJWjZ23TVCU5ZQXTIzQVU3wTZHPclhg$. Triage notifications on the go with GitHub Mobile for iOShttps://urldefense.com/v3/__https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675__;!!NuAq3lKL!7RRmYuoRb9eVgdUSrVaCOO-PzHqmpsASz8_hJWjZ23TVCU5ZQXTIzQVU3wQpSUT-rQ$ or Androidhttps://urldefense.com/v3/__https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign*3Dnotification-email*26utm_medium*3Demail*26utm_source*3Dgithub__;JSUlJSU!!NuAq3lKL!7RRmYuoRb9eVgdUSrVaCOO-PzHqmpsASz8_hJWjZ23TVCU5ZQXTIzQVU3wRH1vepbw$. You are receiving this because you were mentioned.Message ID: @.***>

aravindhebbali commented 2 years ago

Okay.. let me look at it once more and get back to you.

ButlerMSDA commented 2 years ago

Again, thank you so much for looking into this.

I just downloaded the default version from CRAN. I hope you can find this "problem" as I'm very excited to have found a function that returns exactly what yours does and in that format. It's great!

What is funny is that it runs the example code:

model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars) ols_correlations(model)

perfectly, so I really can't understand why my example fails (for me anyway).

Thanks again for this library - it is great

Bob


Robert J. Padgett, Ph. D. Professor of Psychology Butler University 4600 Sunset Ave. Indianapolis, IN 46208 (317) 940-9239


From: Aravind Hebbali @.> Sent: Saturday, December 25, 2021 7:08 AM To: rsquaredacademy/olsrr @.> Cc: Padgett, Robert @.>; Mention @.> Subject: Re: [rsquaredacademy/olsrr] ols_correlations error (Issue #191)

Okay.. let me look at it once more and get back to you.

— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https://github.com/rsquaredacademy/olsrr/issues/191*issuecomment-1001009914__;Iw!!NuAq3lKL!9lRNLWCCpyslukqX2IO20ZpqRZBjijbcNNM7VUGrdODbQttZ1YGaNlSR0E6tPbsh_Q$, or unsubscribehttps://urldefense.com/v3/__https://github.com/notifications/unsubscribe-auth/AU2SRXJKYX4ACBTW67XSR5LUSWX2NANCNFSM5KVWFFIQ__;!!NuAq3lKL!9lRNLWCCpyslukqX2IO20ZpqRZBjijbcNNM7VUGrdODbQttZ1YGaNlSR0E5L2N_jnA$. Triage notifications on the go with GitHub Mobile for iOShttps://urldefense.com/v3/__https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675__;!!NuAq3lKL!9lRNLWCCpyslukqX2IO20ZpqRZBjijbcNNM7VUGrdODbQttZ1YGaNlSR0E7mQg4_yQ$ or Androidhttps://urldefense.com/v3/__https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign*3Dnotification-email*26utm_medium*3Demail*26utm_source*3Dgithub__;JSUlJSU!!NuAq3lKL!9lRNLWCCpyslukqX2IO20ZpqRZBjijbcNNM7VUGrdODbQttZ1YGaNlSR0E7xRHptew$. You are receiving this because you were mentioned.Message ID: @.***>

agustavo87 commented 2 years ago

Getting the same error.

library(olsrr)

df <- data.frame(
  sat = c(1029, 934, 944, 1005, 902, 980, 908, 897, 889, 854),
  expend = c(4.41, 8.96, 4.78, 4.46, 4.99, 5.44, 8.82, 7.03, 5.72, 5.19),
  pctsat = c(61, 32, 27, 66, 11, 62, 3, 3, 36, 16)
)

model <- lm(sat ~ expend + pctsat, data = df)

ols_correlations(model)

getting the following error

Error in model.frame.default(formula = mdata[[1]] ~ ., data = dat, drop.unused.levels = TRUE) : 
  'data' must be a data.frame, environment, or list
> traceback()
12: stop("'data' must be a data.frame, environment, or list")
11: model.frame.default(formula = mdata[[1]] ~ ., data = dat, drop.unused.levels = TRUE)
10: stats::model.frame(formula = mdata[[1]] ~ ., data = dat, drop.unused.levels = TRUE)
9: eval(mf, parent.frame())
8: eval(mf, parent.frame())
7: lm(mdata[[1]] ~ ., data = dat)
6: summary(lm(mdata[[1]] ~ ., data = dat))
5: rtwo(i, mdata)
4: corm2(model)
3: corout(model, corm2(model))
2: ols_correlations.default(model)
1: ols_correlations(model)

Edit: Same with R 4.2.1

agustavo87 commented 2 years ago

If I Copy & Paste the relevant code (for some reason) it works:

Test code:

library(olsrr)
source("olsrr.overrides.R")

df <- data.frame(
  sat = c(1029, 934, 944, 1005, 902, 980, 908, 897, 889, 854),
  expend = c(4.41, 8.96, 4.78, 4.46, 4.99, 5.44, 8.82, 7.03, 5.72, 5.19),
  pctsat = c(61, 32, 27, 66, 11, 62, 3, 3, 36, 16)
)

model <- lm(sat ~ expend + pctsat, data = df)

ols_correlations(model)

# Other error

# insert reprex here
SocComp <- c(8,8,9,10,10,11,11,12,14,16)
IQ <- c(80,80,91,82,106,117,124,98,89,110)
Pop <-  c(1,2,2,1,3,5,2,4,5,5)

df <- data.frame(SocComp,IQ,Pop)
model <- lm (SocComp ~ IQ + Pop, data=df)

ols_correlations(model)
# olsrr.overrides.R
source("olsrr.utils.R")

ols_correlations <- function(model) UseMethod("ols_correlations")

ols_correlations.default <- function(model) {

  check_model(model)

  result <- corout(model, corm2(model))
  class(result) <- c("ols_correlations", "data.frame")
  return(result)

}

print.ols_correlations <- function(x, ...) {
  print_correlations(x)
}

corout <- function(model, r2) {

  r1               <- summary(model)$r.squared
  mdata            <- cordata(model)
  cor_mdata        <- cmdata(mdata)
  n                <- ncol(mdata)
  ksign            <- corsign(model)
  n2               <- n - 1
  parts            <- ksign * sqrt(r1 - r2)
  partials         <- parts / sqrt(1 - r2)
  result           <- data.frame(cor_mdata, partials, parts)
  rownames(result) <- names(ksign)
  colnames(result) <- c("Zero-order", "Partial", "Part")

  return(result)

}

corm2 <- function(model) {

  mdata <- cordata(model)
  n     <- ncol(mdata)
  r2    <- c()

  for (i in 2:n) {
    out <- rtwo(i, mdata)
    r2  <- c(r2, out)
  }

  return(r2)
}

cordata <- function(model) {
  ols_prep_avplot_data(model)
}

cmdata <- function(mdata) {
  cor(mdata)[-1, 1]
}

rtwo <- function(i, mdata) {
  dat <- mdata[, c(-1, -i), drop = FALSE]
  summary(lm(mdata[[1]] ~ ., data = dat))[[8]]
}

corsign <- function(model) {
  sign(summary(model)$coefficients[-1, 1])
}

check_model <- function(model) {
  if (!all(class(model) == "lm")) {
    model_name <- deparse(substitute(model))
    stop(paste0("`", model_name, "` must be an object of class `lm`."), call. = FALSE)
  }
}

print_correlations <- function(data) {

  # number of rows
  nr <- nrow(data)
  vars <- rownames(data)
  cols <- colnames(data)

  # widths
  w1 <- max(nchar("Variable"), nchar(vars))
  w2 <- nchar(cols[1])
  w3 <- nchar(cols[2])
  w4 <- max(nchar(cols[3]), nchar(format(round(data[, 3], 3), nsmall = 3)))
  w <- sum(w1, w2, w3, w4, 12)

  # print
  cat(fc("Correlations", w), "\n")
  cat(rep("-", w), sep = "", "\n")
  cat(fl("Variable", w1), fs(), fc("Zero Order", w2), fs(), fc("Partial", w3), fs(), fc("Part", w4), "\n")
  cat(rep("-", w), sep = "", "\n")
  for (i in seq_len(nr)) {
    cat(
      fl(vars[i], w1), fs(), fg(format(round(data[i, 1], 3), nsmall = 3), w2), fs(),
      fg(format(round(data[i, 2], 3), nsmall = 3), w3), fs(),
      fg(format(round(data[i, 3], 3), nsmall = 3), w4), "\n"
    )
  }
  cat(rep("-", w), sep = "", "\n")
}
# olsrr.utils.R
fs <- function() {
  x <- rep("  ")
  return(x)
}

fg <- function(x, w) {
  z <- as.character(x)
  y <- format(z, width = w, justify = "right")
  return(y)
}

fl <- function(x, w) {
  x <- as.character(x)
  ret <- format(x, width = w, justify = "left")
  return(ret)
}

fc <- function(x, w) {
  x <- as.character(x)
  ret <- format(x, width = w, justify = "centre")
  return(ret)
}

fw <- function(x, w) {
  z <- format(as.character(x), width = w, justify = "right")
  return(z)
}

formatter_t <- function(x, w) {
  ret <- format(x, width = w, justify = "centre")
  return(ret)
}

formatter_n <- function(x, w) {
  ret <- format(x, nsmall = 3)
  ret1 <- format(ret, width = w, justify = "centre")
  return(ret1)
}

format_cil <- function(x, w) {
  ret <- format(x, nsmall = 3)
  ret1 <- format(ret, width = w, justify = "centre")
  return(ret1)
}

format_ciu <- function(x, w) {
  ret <- format(x, nsmall = 3)
  ret1 <- format(ret, width = w, justify = "centre")
  return(ret1)
}

formats_t <- function() {
  x <- rep("  ")
  return(x)
}

l <- function(x) {
  x <- as.character(x)
  k <- grep("\\$", x)
  if (length(k) == 1) {
    temp <- strsplit(x, "\\$")
    out <- temp[[1]][2]
  } else {
    out <- x
  }
  return(out)
}

null_model_metrics <- function(model, full_model) {

  output <- summary(model)
  anovam <- anova(model)
  aic    <- ols_aic(model)
  sbc    <- ols_sbc(model)
  sbic   <- ols_sbic(model, full_model)
  n      <- length(anovam$Df)
  ess    <- anovam$`Sum Sq`[n]
  tss    <- sum(anovam$`Sum Sq`)
  rss    <- tss - ess
  rsq    <- output$r.squared
  adjr   <- output$adj.r.squared
  rmse   <- sqrt(mean(model$residuals ^ 2))

  list(adjr = adjr, aic = aic, sbc = sbc,  sbic = sbic, ess = ess,
       rsq = rsq, rss = rss, rmse = rmse)

}

max_nchar <- function(char, val, rn = 3, ns = 3) {
  max(nchar(char), nchar(format(round(val, rn), nsmall = ns)))
}

#' @importFrom utils packageVersion menu install.packages
check_suggests <- function(pkg) {

  pkg_flag <- tryCatch(utils::packageVersion(pkg), error = function(e) NA)

  if (is.na(pkg_flag)) {

    msg <- message(paste0('\n', pkg, ' must be installed for this functionality.'))

    if (interactive()) {
      message(msg, "\nWould you like to install it?")
      if (utils::menu(c("Yes", "No")) == 1) {
        utils::install.packages(pkg)
      } else {
        stop(msg, call. = FALSE)
      }
    } else {
      stop(msg, call. = FALSE)
    } 
  }

}
agustavo87 commented 2 years ago

The problem seems to arise when the model is limited to two predictors

library(olsrr)

df <- data.frame(
  sat = c(1029, 934, 944, 1005, 902, 980, 908, 897, 889, 854),
  expend = c(4.41, 8.96, 4.78, 4.46, 4.99, 5.44, 8.82, 7.03, 5.72, 5.19),
  pctsat = c(61, 32, 27, 66, 11, 62, 3, 3, 36, 16),
  ptratio = c(17.2, 17.6, 19.3, 17.1, 24, 18.4, 14.4, 16.6, 19.1, 16.3)

)

# With 2 predictors gives error

model.2 <- lm(sat ~ expend + pctsat, data = df)
ols_correlations(model.2)

# With 3 predictors works
model.3 <- lm(sat ~ expend + pctsat + ptratio, data = df)
ols_correlations(model.3)

# Package example with 4 predictors works
olsrr.model.4 <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_correlations(olsrr.model.4)

# Package example with 2 predictors don't work
olsrr.model.2 <- lm(mpg ~ disp + hp, data = mtcars)
ols_correlations(olsrr.model.2)
aravindhebbali commented 2 years ago

Can you check if you still get the error with the development version of the package available on GitHub? The below results are produced with the latest development version.

# Install development version from GitHub
# install.packages("devtools")
devtools::install_github("rsquaredacademy/olsrr")

library(olsrr)
#> 
#> Attaching package: 'olsrr'
#> The following object is masked from 'package:datasets':
#> 
#>     rivers

df <- data.frame(
  sat = c(1029, 934, 944, 1005, 902, 980, 908, 897, 889, 854),
  expend = c(4.41, 8.96, 4.78, 4.46, 4.99, 5.44, 8.82, 7.03, 5.72, 5.19),
  pctsat = c(61, 32, 27, 66, 11, 62, 3, 3, 36, 16),
  ptratio = c(17.2, 17.6, 19.3, 17.1, 24, 18.4, 14.4, 16.6, 19.1, 16.3)
)

# With 2 predictors

model.2 <- lm(sat ~ expend + pctsat, data = df)
ols_correlations(model.2)
#>                Correlations                
#> ------------------------------------------
#> Variable    Zero Order    Partial    Part  
#> ------------------------------------------
#> expend          -0.352      0.138    0.077 
#> pctsat           0.831      0.809    0.757 
#> ------------------------------------------

# With 3 predictors
model.3 <- lm(sat ~ expend + pctsat + ptratio, data = df)
ols_correlations(model.3)
#>                Correlations                 
#> -------------------------------------------
#> Variable    Zero Order    Partial     Part  
#> -------------------------------------------
#> expend          -0.352      0.101     0.056 
#> pctsat           0.831      0.795     0.722 
#> ptratio         -0.054     -0.040    -0.022 
#> -------------------------------------------

# Package example with 4 predictors
olsrr.model.4 <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_correlations(olsrr.model.4)
#>                Correlations                 
#> -------------------------------------------
#> Variable    Zero Order    Partial     Part  
#> -------------------------------------------
#> disp            -0.848      0.048     0.019 
#> hp              -0.776     -0.224    -0.093 
#> wt              -0.868     -0.574    -0.285 
#> qsec             0.419      0.219     0.091 
#> -------------------------------------------

# Package example with 2 predictors
olsrr.model.2 <- lm(mpg ~ disp + hp, data = mtcars)
ols_correlations(olsrr.model.2)
#>                Correlations                 
#> -------------------------------------------
#> Variable    Zero Order    Partial     Part  
#> -------------------------------------------
#> disp            -0.848     -0.606    -0.382 
#> hp              -0.776     -0.326    -0.173 
#> -------------------------------------------

Created on 2022-08-01 by the reprex package (v0.3.0)

agustavo87 commented 2 years ago

Confirmed, working, also with the example @ButlerMSDA.

ButlerMSDA commented 1 year ago

Thanks all, for the fix on this. Sorry it took me so long to get back to this but I only teach the class where I want to use this once a year... When I do teach it, I use RStudio Workbench which is maintained by our IT department. I let them maintain all the correct libraries so I don't have to help 50+ students get that part right and can focus my time on teaching stats. So with this close I hope version ‘0.6.0’ will get moved to CRAN soon so I can have IT get that version loaded on the system for all on use to campus. Again, my thanks for the package and the fix! - Bob