DATA<- read.csv("Vision_Screener.csv")
dfc <- DATA[!is.na(DATA$Od.Gaze.X), ]
dfc <- DATA[!is.na(DATA$Od.Gaze.Y), ]
dfc <- DATA[!is.na(DATA$Os.Rx0), ]
dfc <- DATA[!is.na(DATA$Os.Rx60), ]
dfc <- DATA[!is.na(DATA$Os.Rx120), ]
dfc <- DATA[!is.na(DATA$Od.DS), ]
dfc <- DATA[!is.na(DATA$Od.DC), ]
dfc <- DATA[!is.na(DATA$Od.Pupil.Size), ]
dfc <- DATA[!is.na(DATA$Os.Pupil.Size), ]
dfc <- DATA[!is.na(DATA$Os.Axis), ]
# Select the relevant columns
eye_metrics <- dfc[, c("Od.Gaze.X", "Od.Gaze.Y", "Os.Rx0", "Os.Rx60", "Os.Rx120",
"Od.DS", "Od.DC", "Od.Pupil.Size", "Os.Pupil.Size", "Os.Axis")]
# Compute summary statistics
summary_stats <- data.frame(
Variable = colnames(eye_metrics),
Mean = sapply(eye_metrics, mean, na.rm = TRUE),
Max = sapply(eye_metrics, max, na.rm = TRUE),
Min = sapply(eye_metrics, min, na.rm = TRUE),
SD = sapply(eye_metrics, sd, na.rm = TRUE)
)
# Print the summary statistics
print(summary_stats)
## Variable Mean Max Min SD
## Od.Gaze.X Od.Gaze.X -2.6637313 1.291140 -6.691000 2.0097304
## Od.Gaze.Y Od.Gaze.Y 0.4367579 3.877510 -2.330220 1.4022282
## Os.Rx0 Os.Rx0 -0.4639368 0.292129 -7.905610 1.5660332
## Os.Rx60 Os.Rx60 -0.5104006 0.776246 -7.985900 1.6132618
## Os.Rx120 Os.Rx120 -0.5784772 0.705196 -7.905610 1.5737815
## Od.DS Od.DS -1.0383555 0.327064 -8.646860 1.8102756
## Od.DC Od.DC 0.6340558 1.329510 0.085139 0.3307131
## Od.Pupil.Size Od.Pupil.Size 6.7264037 8.520010 5.379560 0.7332093
## Os.Pupil.Size Os.Pupil.Size 6.7296659 8.953860 5.411180 0.7481709
## Os.Axis Os.Axis -0.2864665 1.432980 -1.614890 0.9771943
Interpupil: A series of numerical values, possibly indicating interpupillary distance.
Od Rx0, Od Rx60, Od Rx120, Od SE: Likely related to different refraction measurements for the right eye.
Od DS, Od DC, Od Axis: Potentially referring to spherical, cylindrical, and axis measurements for the right eye.
Od Pupil Size, Od Gaze S., Od Gaze X, Od Gaze Y: Likely related to pupil size and gaze direction for the right eye.
Os Rx0, Os Rx60, Os Rx120, OS SE: Similar refraction data but for the left eye.
Os DS, Os DC, Os Axis: Spherical, cylindrical, and axis measurements for the left eye.
Os Pupil Size, Os Gaze S., Os Gaze X, Os Gaze Y: Corresponding pupil and gaze measurements for the left eye.
cor_matrix <- cor(dfc[, c("Od.Gaze.X", "Od.Gaze.Y", "Os.Rx0", "Os.Rx60", "Os.Rx120", "Od.DS", "Od.DC", "Od.Pupil.Size", "Os.Pupil.Size", "Os.Axis")], use = "complete.obs")
print(cor_matrix)
## Od.Gaze.X Od.Gaze.Y Os.Rx0 Os.Rx60 Os.Rx120
## Od.Gaze.X 1.00000000 -0.12455320 -0.43491085 -0.476176893 -0.439528071
## Od.Gaze.Y -0.12455320 1.00000000 -0.02802631 -0.031961513 -0.047706575
## Os.Rx0 -0.43491085 -0.02802631 1.00000000 0.969743158 0.976093986
## Os.Rx60 -0.47617689 -0.03196151 0.96974316 1.000000000 0.990938766
## Os.Rx120 -0.43952807 -0.04770658 0.97609399 0.990938766 1.000000000
## Od.DS -0.48284673 0.01493917 0.92993598 0.927401077 0.939587632
## Od.DC -0.17094630 0.09570953 0.10676033 0.004288583 -0.005566962
## Od.Pupil.Size -0.11805530 0.07315319 0.02189132 -0.068721983 -0.069791009
## Os.Pupil.Size 0.01816916 0.04545832 -0.02485687 -0.128731966 -0.120139093
## Os.Axis 0.43636154 -0.10360880 -0.33258484 -0.329260404 -0.247042010
## Od.DS Od.DC Od.Pupil.Size Os.Pupil.Size Os.Axis
## Od.Gaze.X -0.48284673 -0.170946299 -0.118055298 0.01816916 0.4363615
## Od.Gaze.Y 0.01493917 0.095709530 0.073153191 0.04545832 -0.1036088
## Os.Rx0 0.92993598 0.106760334 0.021891320 -0.02485687 -0.3325848
## Os.Rx60 0.92740108 0.004288583 -0.068721983 -0.12873197 -0.3292604
## Os.Rx120 0.93958763 -0.005566962 -0.069791009 -0.12013909 -0.2470420
## Od.DS 1.00000000 -0.038951869 -0.022898434 -0.06138751 -0.2612150
## Od.DC -0.03895187 1.000000000 -0.003585142 0.02274167 -0.2783945
## Od.Pupil.Size -0.02289843 -0.003585142 1.000000000 0.93790709 -0.1771932
## Os.Pupil.Size -0.06138751 0.022741666 0.937907090 1.00000000 -0.1219021
## Os.Axis -0.26121499 -0.278394491 -0.177193235 -0.12190207 1.0000000
#Visualize
pairs(dfc[, c("Od.Gaze.X", "Od.Gaze.Y", "Os.Rx0", "Os.Rx60", "Os.Rx120", "Od.DS", "Od.DC", "Od.Pupil.Size", "Os.Pupil.Size", "Os.Axis")])
Os.Rx0, Os.Rx60, and Os.Rx120 are highly correlated (~0.97-0.99), meaning they measure very similar aspects of vision.
Od.DS is also highly correlated with these (~0.93-0.94), indicating a strong relationship between sphere power and these refraction values.
This suggests that as the right eye gaze position (X-axis) shifts, these refractive values tend to decrease.
Could indicate an association between gaze alignment and refraction.
Implies that gaze position (X) is somewhat related to astigmatism axis measurements.
Od.Pupil.Size and Os.Pupil.Size are highly correlated (0.94), which makes sense because pupil size is often similar between eyes.
Pupil sizes are weakly correlated with most refractive values (-0.06 to -0.12), suggesting they don’t strongly impact refraction in this dataset.
Od.DC (Cylindrical power) is mostly uncorrelated with other variables (-0.03 to 0.10).
It seems relatively independent, meaning cylindrical power might not be influenced by gaze position or other refraction values in this data.
# If there is a variablity between subj
# Install package if not already installed
# Load the package
library(irr)
## Loading required package: lpSolve
# Compute ICC for a variable (e.g., Od.Gaze.X)
icc_result <- icc(dfc[, c("Od.Gaze.X", "Od.Gaze.Y")], model="oneway", type="consistency", unit="single")
print(icc_result)
## Single Score Intraclass Correlation
##
## Model: oneway
## Type : consistency
##
## Subjects = 27
## Raters = 2
## ICC(1) = -0.504
##
## F-Test, H0: r0 = 0 ; H1: r0 > 0
## F(26,27) = 0.33 , p = 0.997
##
## 95%-Confidence Interval for ICC Population Values:
## -0.736 < ICC < -0.162
Negative ICC (-0.504): This means that within-subject variance is greater than between-subject variance. Essentially, there is no consistency between subjects, and the data may contain noise or measurement errors.
F-Test p-value (0.997, very high): This indicates no significant difference between subjects, meaning the variability is mostly random.
Confidence Interval (-0.736 to -0.162): A negative range means the model does not capture reliable subject-level differences.
library(car)
## Loading required package: carData
#visualize Data to Spot Issues:
boxplot(Od.Gaze.X ~ as.factor(Id), data = dfc, main="Od.Gaze.X Variability Across Subjects", ylab="Od.Gaze.X")
#If the boxplots look very different, variability between subjects is high.
#If they look similar, most of the variance is within subjects, not between them.
library(ggplot2)
ggplot(dfc, aes(x = Od.Gaze.X)) +
geom_histogram(binwidth = 1, fill = "blue", alpha = 0.6) +
theme_minimal()
library(ggplot2)
library(car)
dfc_subset <- dfc[, 18:40]
# List of numeric variables
numeric_vars <- names(dfc_subset)[sapply(dfc_subset, is.numeric)]
# Create boxplots and histograms for each numeric variable
lapply(numeric_vars, function(var) {
# Boxplot
boxplot(dfc[[var]] ~ as.factor(dfc$Id),
main = paste(var, "Variability Across Subjects"),
ylab = var)
# Histogram
ggplot(dfc, aes(x = .data[[var]])) +
geom_histogram(binwidth = 1, fill = "blue", alpha = 0.6) +
theme_minimal() +
ggtitle(paste("Histogram of", var))
})
## [[1]]
##
## [[2]]
##
## [[3]]
##
## [[4]]
##
## [[5]]
##
## [[6]]
##
## [[7]]
##
## [[8]]
##
## [[9]]
##
## [[10]]
##
## [[11]]
##
## [[12]]
##
## [[13]]
##
## [[14]]
##
## [[15]]
##
## [[16]]
##
## [[17]]
##
## [[18]]
##
## [[19]]
##
## [[20]]
##
## [[21]]
#Data Distribution
t.test(dfc$Od.Gaze.X, dfc$Os.Rx0, paired=TRUE) # Example
##
## Paired t-test
##
## data: dfc$Od.Gaze.X and dfc$Os.Rx0
## t = -3.7626, df = 26, p-value = 0.0008657
## alternative hypothesis: true mean difference is not equal to 0
## 95 percent confidence interval:
## -3.4015629 -0.9980261
## sample estimates:
## mean difference
## -2.199795
wilcox.test(dfc$Od.Gaze.X, dfc$Os.Rx0, paired=TRUE) # If non-normal
##
## Wilcoxon signed rank exact test
##
## data: dfc$Od.Gaze.X and dfc$Os.Rx0
## V = 36, p-value = 7.29e-05
## alternative hypothesis: true location shift is not equal to 0
#Predict one variable using others (example: Od.Gaze.X vs. other factors).
lm_model <- lm(Od.Gaze.X ~ Od.Gaze.Y + Os.Rx0 + Os.Rx60 + Os.Rx120 + Od.DS + Od.DC + Od.Pupil.Size + Os.Pupil.Size + Os.Axis, data=dfc)
summary(lm_model)
##
## Call:
## lm(formula = Od.Gaze.X ~ Od.Gaze.Y + Os.Rx0 + Os.Rx60 + Os.Rx120 +
## Od.DS + Od.DC + Od.Pupil.Size + Os.Pupil.Size + Os.Axis,
## data = dfc)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.0296 -0.5964 0.1860 0.5611 2.2387
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.41224 3.81867 0.370 0.7161
## Od.Gaze.Y -0.02632 0.24689 -0.107 0.9164
## Os.Rx0 2.16355 1.42412 1.519 0.1471
## Os.Rx60 -1.17148 2.18731 -0.536 0.5992
## Os.Rx120 -0.36325 2.80855 -0.129 0.8986
## Od.DS -0.93024 0.58138 -1.600 0.1280
## Od.DC -2.04623 1.27762 -1.602 0.1277
## Od.Pupil.Size -2.60922 1.37262 -1.901 0.0744 .
## Os.Pupil.Size 2.10241 1.35750 1.549 0.1399
## Os.Axis 0.47175 0.54423 0.867 0.3981
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.703 on 17 degrees of freedom
## Multiple R-squared: 0.5307, Adjusted R-squared: 0.2823
## F-statistic: 2.136 on 9 and 17 DF, p-value: 0.08495
#Reduce dimensionality and find key relationships.
pca_result <- prcomp(dfc[, c("Od.Gaze.X", "Od.Gaze.Y", "Os.Rx0", "Os.Rx60", "Os.Rx120", "Od.DS", "Od.DC", "Od.Pupil.Size", "Os.Pupil.Size", "Os.Axis")], scale=TRUE)
summary(pca_result)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6 PC7
## Standard deviation 2.0714 1.4289 1.1538 0.96791 0.84684 0.7287 0.29430
## Proportion of Variance 0.4291 0.2042 0.1331 0.09369 0.07171 0.0531 0.00866
## Cumulative Proportion 0.4291 0.6332 0.7664 0.86005 0.93176 0.9849 0.99352
## PC8 PC9 PC10
## Standard deviation 0.2122 0.12738 0.05986
## Proportion of Variance 0.0045 0.00162 0.00036
## Cumulative Proportion 0.9980 0.99964 1.00000
#biplot(pca_result)
No strong predictors for Od.Gaze.X:
The model is not statistically significant.
The best potential predictor is Od.Pupil.Size (p = 0.074).
PCA suggests refractive error measures (Os.Rx0, Os.Rx60, Os.Rx120) behave similarly:
These could be grouped into a single factor instead of separate predictors.
anova(lm(Od.Gaze.X ~ Os.Rx0, data=dfc))
## Analysis of Variance Table
##
## Response: Od.Gaze.X
## Df Sum Sq Mean Sq F value Pr(>F)
## Os.Rx0 1 19.863 19.863 5.8317 0.02338 *
## Residuals 25 85.151 3.406
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
In the correlation matrix you provided earlier, Os.Rx0 was highly correlated with Os.Rx60 (r = 0.97) and Os.Rx120 (r = 0.98).
This means these variables are redundant predictors. When you include multiple highly correlated variables in a regression, they compete to explain the same variance in Od.Gaze.X, which can lead to inflated standard errors and insignificant p-values.
This is why Os.Rx0 alone was significant in ANOVA, but in multiple regression, its effect was shared with Os.Rx60 and Os.Rx120, making it lose significance.
B. Shared Variance with Other Predictors The multiple regression model calculates the effect of Os.Rx0 while controlling for all other variables. If another variable (e.g., Os.Rx60 or Os.Rx120) explains a lot of the same variation in Od.Gaze.X, then the unique contribution of Os.Rx0 becomes smaller, making it insignificant.
C. Overfitting / Model Complexity Your regression model included 9 predictors with only 28 participants. This is a lot of predictors for a small dataset, which can lead to overfitting, making individual predictors appear non-significant.
The adjusted R² (0.2823) suggests that the model only explains about 28% of the variance, meaning some variables might be unnecessary.