Search code examples
rstatisticslinear-regressionlogistic-regressionscaling

ordinal logistic regression with continuous variables - scaling


I have been learning about the logistic regression and came upon this great post with an R data analysis example. I have adapted the code for my analysis and everything has worked fine so far.

I do have a continuous predictor. I have used the commands to obtain a table that displays the (linear) predicted values we would get if we regressed our dependent variable on our predictor variables one at a time. However, the command seems to be cponverting the continous variable into a categorical one.

> ## Ordinal logistic regression (OLR) ## 
> # https://stats.idre.ucla.edu/r/dae/ordinal-logistic-regression/
> mod_OLRfull <- polr(Percentage_f ~ Gender + SE_track + Total_testscore, data = mydata, Hess=TRUE)

> # calculate essential metrics
> ctable <- coef(summary(mod_OLRfull))
> p <- pnorm(abs(ctable[, "t value"]), lower.tail = FALSE) * 2
> ctable <- cbind(ctable, "p value" = p)

> # check if assumption holds: proportional odds
> sf <- function(y) {
+   c('Y>=1' = qlogis(mean(y >= 1)),
+     'Y>=2' = qlogis(mean(y >= 2)),
+     'Y>=3' = qlogis(mean(y >= 3)))#,
+ #    'Y>=4' = qlogis(mean(y >= 4)))
+ }
> s <- with(mydata, summary(as.numeric(Percentage_f) ~ Gender + SE_track + Total_testscore, fun=sf))
> s
as.numeric(Percentage_f)     N= 286 

+---------------+-------+---+----+---------+----------+
|               |       |N  |Y>=1|Y>=2     |Y>=3      |
+---------------+-------+---+----+---------+----------+
|Gender         |male   | 97|Inf |1.2862109|-1.1685709|
|               |female |189|Inf |1.5170646|-0.8397507|
+---------------+-------+---+----+---------+----------+
|SE_track       |KSO    | 39|Inf |1.0647107|-1.3545457|
|               |TSO    | 40|Inf |0.7308875|-1.7346011|
|               |ASO    |207|Inf |1.6990501|-0.7591051|
+---------------+-------+---+----+---------+----------+
|Total_testscore|[ 2, 8)| 74|Inf |0.8602013|-1.6422277|
|               |[ 8,11)|104|Inf |1.6326948|-1.3156768|
|               |[11,13)| 58|Inf |1.3437347|-0.5663955|
|               |[13,16]| 50|Inf |2.4423470| 0.0000000|
+---------------+-------+---+----+---------+----------+
|Overall        |       |286|Inf |1.4350845|-0.9458495|
+---------------+-------+---+----+---------+----------+
> glm(I(as.numeric(Percentage_f) >= 2) ~ Gender + SE_track + Total_testscore, family = "binomial", data = mydata)

Call:  glm(formula = I(as.numeric(Percentage_f) >= 2) ~ Gender + SE_track + 
    Total_testscore, family = "binomial", data = mydata)

> glm(I(as.numeric(Percentage_f) >= 3) ~ Gender + SE_track + Total_testscore, family = "binomial", data = mydata)

> glm(I(as.numeric(Percentage_f) >= 4) ~ Gender + SE_track + Total_testscore, family = "binomial", data = mydata)


> s[, 4] <- s[, 4] - s[, 3]
> s[, 3] <- s[, 3] - s[, 3]
> s
as.numeric(Percentage_f)     N= 286 

+---------------+-------+---+----+----+---------+
|               |       |N  |Y>=1|Y>=2|Y>=3     |
+---------------+-------+---+----+----+---------+
|Gender         |male   | 97|Inf |0   |-2.454782|
|               |female |189|Inf |0   |-2.356815|
+---------------+-------+---+----+----+---------+
|SE_track       |KSO    | 39|Inf |0   |-2.419256|
|               |TSO    | 40|Inf |0   |-2.465489|
|               |ASO    |207|Inf |0   |-2.458155|
+---------------+-------+---+----+----+---------+
|Total_testscore|[ 2, 8)| 74|Inf |0   |-2.502429|
|               |[ 8,11)|104|Inf |0   |-2.948372|
|               |[11,13)| 58|Inf |0   |-1.910130|
|               |[13,16]| 50|Inf |0   |-2.442347|
+---------------+-------+---+----+----+---------+
|Overall        |       |286|Inf |0   |-2.380934|
+---------------+-------+---+----+----+---------+

QUESTION:

How can I change that my variable Total_testscore is split in intervals [ 2, 8), [ 8,11), [11,13), [13,16] ? I would like to change them to [ 0, 5), [ 5,10), [10,13), [13,16]


Solution

  • The solution is to scale the continuous variable before it is used in the regression, using:

    starters$Total_testscore_f <- cut(starters$Total_testscore, breaks = c(0,5,10,13,16))
    
    s <- with(mydata, summary(as.numeric(Percentage_f) ~ Gender + SE_track + Total_testscore_f, fun=sf))
    glm(I(as.numeric(Percentage_f) >= 2) ~ Gender + SE_track + Total_testscore_f, family = "binomial", data = mydata)
    glm(I(as.numeric(Percentage_f) >= 3) ~ Gender + SE_track + Total_testscore_f, family = "binomial", data = mydata)
    glm(I(as.numeric(Percentage_f) >= 4) ~ Gender + SE_track + Total_testscore_f, family = "binomial", data = mydata)
    s[, 4] <- s[, 4] - s[, 3]
    s[, 3] <- s[, 3] - s[, 3]
    s
    
    # plot 
    par(mfrow = c(1,1))
    plot(s, which=1:3, pch=1:3, xlab='logit', main=' ', xlim = c(-3,0))#xlim=range(s[,3:4]))
    #  suggesting that the proportional odds assumption may not hold
    
    as.numeric(Percentage_f)     N= 286 , 2 Missing 
    
    +-----------------+-------+---+----+----+---------+
    |                 |       |N  |Y>=1|Y>=2|Y>=3     |
    +-----------------+-------+---+----+----+---------+
    |Gender           |male   | 97|Inf |0   |-2.454782|
    |                 |female |189|Inf |0   |-2.356815|
    +-----------------+-------+---+----+----+---------+
    |SE_track         |KSO    | 39|Inf |0   |-2.419256|
    |                 |TSO    | 40|Inf |0   |-2.465489|
    |                 |ASO    |207|Inf |0   |-2.458155|
    +-----------------+-------+---+----+----+---------+
    |Total_testscore_f|(0,5]  | 25|Inf |0   |-1.912387|
    |                 |(5,10] |153|Inf |0   |-2.956124|
    |                 |(10,13]| 81|Inf |0   |-2.096264|
    |                 |(13,16]| 27|Inf |0   |-2.151035|
    +-----------------+-------+---+----+----+---------+
    |Overall          |       |286|Inf |0   |-2.380934|
    +-----------------+-------+---+----+----+---------+