data cleaning

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(psych)
## 
## Attaching package: 'psych'
## 
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:psych':
## 
##     logit
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
## 
## The following object is masked from 'package:purrr':
## 
##     some
library(multcomp)
## Loading required package: mvtnorm
## Loading required package: survival
## Loading required package: TH.data
## Loading required package: MASS
## 
## Attaching package: 'MASS'
## 
## The following object is masked from 'package:dplyr':
## 
##     select
## 
## 
## Attaching package: 'TH.data'
## 
## The following object is masked from 'package:MASS':
## 
##     geyser
library(cowplot)
## 
## Attaching package: 'cowplot'
## 
## The following object is masked from 'package:lubridate':
## 
##     stamp
#data cleaning

dataset <- read_csv("dataset_123.csv")
## Rows: 300 Columns: 16
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr   (1): Treatment
## dbl  (13): Lizard, year, Aggression, Boldness, sex, avgmass, trialnum, ticks...
## date  (2): date, date_infected
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
cleandata<- dataset %>%
  dplyr::select(Aggression, avgmass, Treatment, avgtotal) %>%  #select all columns included in analysis
  drop_na(avgmass, Treatment, avgtotal) # remove all rows with NAs
#creating categories for aggression to simplify viewing/interpretation
cut_points <- c(0, 3, 7, 11)  
labels <- c("low", "medium", "high")
# Convert the Aggression column to a categorical variable
cleandata$AggressionCategory <- cut(cleandata$Aggression, breaks = cut_points, labels = labels)

testing normality

#RAW AND TRANSFORMED DATA FAILED TO BE NORMAL
mass_hist<- ggplot(data= cleandata, aes(x = avgmass)) + #checking normality visually of avg mass of lizard
  geom_histogram(fill = "darkgreen", border = "grey")+ #picking colors- green bc lizards!
  theme_bw()+ #simple theme
  labs(x= "Average Mass", y= "Frequency")+ #axis lables
  theme((axis.title= element_text(face="bold", size = 12))) #font size
## Warning in geom_histogram(fill = "darkgreen", border = "grey"): Ignoring
## unknown parameters: `border`
mass_hist #looks fairly normal but has some dips
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# qqPlot of y-variable
qqPlot(cleandata$avgmass) #almost all points fall in boundary line!

## [1] 255 295
# shapiro-wilks test of y-variable
shapiro.test(cleandata$avgmass) #P is less than 0.05 (alpha), must reject the null that the data is normally distributed
## 
##  Shapiro-Wilk normality test
## 
## data:  cleandata$avgmass
## W = 0.98855, p-value = 0.01819
######testing transformations to attempt to get normal distribution 
min(cleandata$avgmass) # not zeros! good to take log
## [1] 445
cleandata$log_avgmass <- log(cleandata$avgmass) #log transformation
## Transformation 1 - LOG code 
logmass_hist<- ggplot(data= cleandata, aes(x = log_avgmass)) + 
  geom_histogram(fill = "darkgreen", border = "grey")+ #picking colors- green bc lizards!
  theme_bw()+ #simple theme
  labs(x= "Log Average Mass", y= "Frequency")+ #axis lables
  theme((axis.title= element_text(face="bold", size = 12))) #font size
## Warning in geom_histogram(fill = "darkgreen", border = "grey"): Ignoring
## unknown parameters: `border`
logmass_hist #looks like data is now skewed right... less normal than before
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

qqPlot(cleandata$log_avgmass)#definitely some points out of bounds

## [1] 255 295
shapiro.test(cleandata$log_avgmass) #NOPE! still not normal p<0.05
## 
##  Shapiro-Wilk normality test
## 
## data:  cleandata$log_avgmass
## W = 0.96993, p-value = 6.507e-06
## Transformation 1 code

cleandata$sqrt_avgmass <- sqrt(cleandata$avgmass) #sqrt transformation
sqrtmass_hist<- ggplot(data= cleandata, aes(x = sqrt_avgmass)) + #checking normality visually of avg mass of lizard
  geom_histogram(fill = "darkgreen", border = "grey")+ #picking colors- green bc lizards!
  theme_bw()+ #simple theme
  labs(x= "Square Root Average Mass", y= "Frequency")+ #axis lables
  theme((axis.title= element_text(face="bold", size = 12))) #font size
## Warning in geom_histogram(fill = "darkgreen", border = "grey"): Ignoring
## unknown parameters: `border`
sqrtmass_hist #also looks like data is now skewed right... less normal than before
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

qqPlot(cleandata$sqrt_avgmass)#definitely some points out of bounds

## [1] 255 295
shapiro.test(cleandata$sqrt_avgmass) #NOPE! still not normal p<0.05
## 
##  Shapiro-Wilk normality test
## 
## data:  cleandata$sqrt_avgmass
## W = 0.98102, p-value = 0.0005206

plots of variable of interest

## plot y~x(numeric)
numscatter <-ggplot(data= cleandata, aes(x= avgtotal, y = avgmass)) +
  geom_point()+
  theme_bw()+
  labs(x= "Average Total Ticks", y= "Average Mass")+
  theme(axis.title= element_text(face="bold", size = 12)) 

numscatter

###plot y~x(categorical)
agro_boxplot<-ggplot(data= cleandata, aes(x= AggressionCategory, y = avgmass)) +
  geom_boxplot(fill = "#7bbfc9")+
  aes(group = Aggression)+
  theme_bw()+
  labs(x= "Aggression Score", y= "Average Mass")+
  theme(axis.title= element_text(face="bold", size = 12)) 

agro_boxplot

###plot y~x(categorical)
treat_scatter<-ggplot(data= cleandata, aes(x= Treatment, y = avgmass)) +
  geom_boxplot(fill = "#7bbfc9")+
  theme_bw()+
  labs(x= "Treatment", y= "Average Mass")+
  theme(axis.title= element_text(face="bold", size = 12)) 

treat_scatter

stat test 1- Mann-Whitney-U

#test research question 1- Do lizards have significantly different body masses when infested vs. not?

#see earlier that data does not pass assumptions for parametric test, comparing two different groups of untransformed data
##COMPARING HUMAN INTERFERENCE INFESTION TREATMENT
selected_treatment <- cleandata%>% #only comparing those that were exposed to same conditions
  filter(Treatment %in% c("infestation", "no_infestation"))

wilcox.test(selected_treatment$avgmass ~ selected_treatment$Treatment) #nonparametric eq of two-sample t-test, test if medians dif from eachother 
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  selected_treatment$avgmass by selected_treatment$Treatment
## W = 2316, p-value = 0.8112
## alternative hypothesis: true location shift is not equal to 0
#COMPARING WILD INFESTATION
selected_treatment2 <- cleandata%>% #only comparing those that were exposed to same conditions
  filter(Treatment %in% c("no_treatment"))
cut_points <- c(-Inf, 1, +Inf)  
labels <- c("no_infestation", "infestation")
# Convert the Aggression column to a categorical variable
selected_treatment2$notreatmentinfestationCategory <- cut(selected_treatment2$avgtotal, breaks = cut_points, labels = labels)

wilcox.test(selected_treatment2$avgmass ~ selected_treatment2$notreatmentinfestationCategory) #nonparametric eq of two-sample t-test, test if medians dif from eachother 
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  selected_treatment2$avgmass by selected_treatment2$notreatmentinfestationCategory
## W = 2176.5, p-value = 0.05243
## alternative hypothesis: true location shift is not equal to 0
#p-value = 0.05243 more than 0.05 fail to reject

stat test 2- correlation

library(psych)
#selecting numerical columns to perform test on

cleandata_numeric<- cleandata%>%
  dplyr::select(avgmass, avgtotal) #variables of interest
#check assumptions
pairs.panels(cleandata_numeric, #avg total has hard left sqew
             density = TRUE,
             cor= TRUE,
             lm= TRUE)

#transformation trial
#cleandata$log_avgtotal <- log(cleandata$avgtotal+1) #log transformation
#cleandata$sqrt_avgtotal <- sqrt(cleandata$avgtotal) #log transformation

#take 2 pairs panel
#cleandata_numeric2<- cleandata%>%
#  dplyr::select(log_avgmass, log_avgtotal, sqrt_avgmass, sqrt_avgtotal) #variables of interest
  
 

#pairs.panels(cleandata_numeric2, #log transform looks best- sticking with that ... though the correlation is very low
#             density = TRUE,
#             cor= TRUE,
#             lm= TRUE)
#str(cleandata_numeric2)
#Run a Pearson's correlation test bc match assumptions with log transformation
cor.test(cleandata$avgmass, #one numeric
         cleandata$avgtotal, # second num
         method = "spearman", #MUST say pearson or spearman- sp bc not normal
         alternative = "two.sided") # bc value can be above OR below threshold ---> 2 sided
## Warning in cor.test.default(cleandata$avgmass, cleandata$avgtotal, method =
## "spearman", : Cannot compute exact p-value with ties
## 
##  Spearman's rank correlation rho
## 
## data:  cleandata$avgmass and cleandata$avgtotal
## S = 3866510, p-value = 0.01468
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.1407659
#p-value = 0.01468, reject null!

linear regression - do I need to include thise since pairs panel showed no corr?

#linear regression model??
model<- lm(avgmass ~ avgtotal,
               data = cleandata)
par(mfrow = c(2,2))
plot(model)

test <- sample(1:nrow(cleandata), 15, replace = F) # pick 15 random rows from air_quality, don't replace
mass_train <- cleandata[-test,] # leave those rows out of training data
mass_test <- cleandata[test,] # use those rows to create a set of test data


## Step 10. Use the best fit model on TRAINING set
fit_mass <- lm(avgmass ~ avgtotal,
               data = mass_train)

## Step 11. Use the fitted model with training data to make predictions of your Y outcome
fit_mass_train <- predict(fit_mass, 
                                  mass_test)


## Step 12. Visualize how your best fit model did with predictions
plot(mass_test$avgmass, pch = 1, ylab = "Avg Mass")+ # plot actual test data values
points(fit_mass_train, pch = 20, col = "red") # plot the model predictions for those points
## integer(0)
#clearly, log total avg total is a poor predictor of avg mass