Dante Goss II Final Project

This is document will provide a background of the data and its collection, how I prepared it for analysis, and the analysis itself. Background: This is pilot data I collected earlier in the semester. It comes from a device called the “Loadsol” which are basically force plates in the form of an insole. I’m interested in the effect of cadence on knee joint loading, which I’m using ground reaction force as a surrogate of. I wore the sensors and walked at increasing cadences on a treadmill, giving me the ability to hold speed constant. For this preliminary analysis I’ll be looking at cadences of 100, 110, 120, and 130 steps per minute at 2.2 miles per hour. These numbers were chosen based on previous research, with 2.2 miles per hour being the self selected speed of many adults with knee osteoarthritis, and cadence ranging between 100 and 130 depending on intensity. The data in it’s raw form is essentially a long time series with forces in the heel, midfoot, and forefoot of each foot, along with a total. My goal is to look at 5 consecutive steps for each cadence on both legs, compare the waveforms themselves graphically, as well as statistically via their averages.

Load in data

I make sure my directory exists, set the directory, check the file, and load in the data.

#check the path exists (2 Points-dir.exists)
dir.exists("C:/Users/ddg12/OneDrive - University of Virginia/Loadsol")
## [1] TRUE
#set the path 
setwd("C:/Users/ddg12/OneDrive - University of Virginia/Loadsol")
#Check if file exists (2 Points-file.exists)
file.exists("Cadence Trials (DG 3-24).txt")
## [1] TRUE
#Read in data (1 Point-R)
DGalldata<-as.data.frame(read.table("Cadence Trials (DG 3-24).txt",header=TRUE,sep = "\t"))
#Cadence Trials (JX 3-24).txt
#DGalldata<-as.data.frame(read.table("Cadence Trials (JX 3-24).txt",header=TRUE,sep = "\t"))

Start prepping data

Now that I have the data, I start off by getting rid of some extra columns (one was created by there being an extra tab in my import, one is because the data lists time for both legs simultaneously). I save the original names to a variable since it has the name of the sensor (I would like to record which sensors I used). Then I rename the columns to remove the sensor number.

head(DGalldata)
#get rid of extra column $NA (1 Point-subset)
DGalldata<-DGalldata[-11]
head(DGalldata)
#Get rid of the extra time column
DGalldata <- DGalldata[-6]
#Check if column names are correct (1 Point-head)
head(DGalldata)
names(DGalldata)
## [1] "Time"               "PRX189.L..Heel"     "PRX189.L..Midfoot" 
## [4] "PRX189.L..Forefoot" "PRX189.L"           "PRX198.R..Forefoot"
## [7] "PRX198.R..Midfoot"  "PRX198.R..Heel"     "PRX198.R"
#Store original names since they have sensor values (1 Point-print)
OGnames <- print(names(DGalldata))
## [1] "Time"               "PRX189.L..Heel"     "PRX189.L..Midfoot" 
## [4] "PRX189.L..Forefoot" "PRX189.L"           "PRX198.R..Forefoot"
## [7] "PRX198.R..Midfoot"  "PRX198.R..Heel"     "PRX198.R"
#change names of columns to add units (1 Point-changing names)
names(DGalldata) <-c("Time","LeftHeel(N)", "LeftMidfoot(N)", "LeftForefoot(N)",
  "LeftTotalForce","RightForefoot(N)", "RightMidfoot(N)",
  "RightHeel(N)", "RightTotal(N)")

Isolate waveforms

Now I went ahead and isolated the individual waveforms. The first step for this is putting in a threshold, in my case any data in the total force columns below 20N meant the foot wasn’t in contact with the ground. I made a list of all the indices where the data was below 20N in the total force columns (one for each leg).

#tells me when the value is less than 20
LeftLegFilter<-which(DGalldata[5]<20)
#LeftLegFilter<-as.data.frame(LeftLegFilter) #(1 Point-Change data type)
LeftLegFilter<-cbind(LeftLegFilter,diff(LeftLegFilter))#find differences for easier searching
## Warning in cbind(LeftLegFilter, diff(LeftLegFilter)): number of rows of result
## is not a multiple of vector length (arg 2)
head(LeftLegFilter)
##      LeftLegFilter  
## [1,]            67 1
## [2,]            68 1
## [3,]            69 1
## [4,]            70 1
## [5,]            71 1
## [6,]            72 1
#Right leg
RightLegFilter<-which(DGalldata$`RightTotal(N)`<20)
#RightLegFilter<-as.data.frame(RightLegFilter)
RightLegFilter<- cbind(RightLegFilter,diff(RightLegFilter))
## Warning in cbind(RightLegFilter, diff(RightLegFilter)): number of rows of
## result is not a multiple of vector length (arg 2)
head(RightLegFilter)
##      RightLegFilter  
## [1,]             20 1
## [2,]             21 1
## [3,]             22 1
## [4,]             23 1
## [5,]             24 1
## [6,]             25 1

Create data frames for waveforms

Going into this I already knew what timestamps would correspond to each cadence, so I used the filters to choose 5 consecutive cycles. I created data frames for each cycle including all the partial foot and total foot data, then put all of the 5 waveforms for once cadence on one leg into a list.

#based on known timestamps for each protocol, find 5 gait cycles in each
#100 SPM 1000-3000
Left100S1<-DGalldata[1490:1567,1:5]
Left100S2<-DGalldata[1610:1686,1:5]
Left100S3<-DGalldata[1729:1806,1:5]
Left100S4<-DGalldata[1851:1927,1:5]
Left100S5<-DGalldata[1972:2047,1:5]
left100list<- list(Left100S1,Left100S2,Left100S3,Left100S4,Left100S5)#puts all the data into a list

Right100S1<-DGalldata[1428:1509,c(1,6:9)]
Right100S2<- DGalldata[1549:1630,c(1,6:9)]
Right100S3<- DGalldata[1669:1753,c(1,6:9)]
Right100S4<- DGalldata[1789:1867,c(1,6:9)]
Right100S5<- DGalldata[1911:1988,c(1,6:9)]
right100list<- list(Right100S1,Right100S2,Right100S3,Right100S4,Right100S5) #2 Points (lists)

#110  SPM     4100-5400
Left110S1<- DGalldata[4647:4717,1:5]
Left110S2<- DGalldata[4756:4826,1:5]
Left110S3<- DGalldata[4865:4935,1:5]
Left110S4<- DGalldata[4973:5043,1:5]
Left110S5<- DGalldata[5083:5153,1:5]
left110list<- list(Left110S1,Left110S2,Left110S3,Left110S4,Left110S5)

Right110S1<- DGalldata[4701:4776,c(1,6:9)]
Right110S2<- DGalldata[4808:4882,c(1,6:9)]
Right110S3<- DGalldata[4917:4989,c(1,6:9)]
Right110S4<- DGalldata[5025:5102,c(1,6:9)]
Right110S5<- DGalldata[5136:5211,c(1,6:9)]
right110list<- list(Right110S1,Right110S2,Right110S3,Right110S4,Right110S5)

#120 SPM   6000-8000
Left120S1<- DGalldata[7007:7073,1:5]
Left120S2<- DGalldata[7105:7169,1:5]
Left120S3<- DGalldata[7202:7268,1:5]
Left120S4<- DGalldata[7304:7371,1:5]
Left120S5<- DGalldata[7404:7473,1:5]
left120list<- list(Left120S1,Left120S2,Left120S3,Left120S4,Left120S5)

Right120S1<- DGalldata[7055:7126,c(1,6:9)]
Right120S2<- DGalldata[7152:7222,c(1,6:9)]
Right120S3<- DGalldata[7251:7321,c(1,6:9)]
Right120S4<- DGalldata[7353:7422,c(1,6:9)]
Right120S5<- DGalldata[7453:7522,c(1,6:9)]
right120list<- list(Right120S1,Right120S2,Right120S3,Right120S4,Right120S5)

#130  SPM   8600-9900
Left130S1<- DGalldata[9042:9103,1:5]
Left130S2<- DGalldata[9133:9196,1:5]
Left130S3<- DGalldata[9225:9289,1:5]
Left130S4<- DGalldata[9319:9382,1:5]
Left130S5<- DGalldata[9412:9472,1:5]
left130list<- list(Left130S1,Left130S2,Left130S3,Left130S4,Left130S5)

Right130S1<- DGalldata[9086:9156,c(1,6:9)]
Right130S2<- DGalldata[9177:9245,c(1,6:9)]
Right130S3<- DGalldata[9272:9338,c(1,6:9)]
Right130S4<- DGalldata[9363:9432,c(1,6:9)]
Right130S5<- DGalldata[9456:9521,c(1,6:9)]
right130list<- list(Right130S1,Right130S2,Right130S3,Right130S4,Right130S5)

Create New Time Variable

Each of the above variables “Time” column is going to start at some number that isn’t 0. To create clean graphs I needed to create a new “Time” column that starts at 0, increases at the same sampling rate, and stops with the same number of elements as the old variable. To accomplish this I used a loop. After I had this I renamed all the variables again since the new time variable was unnamed.

#100 SPM Left
listcheck<-list()
firstcheck<-list()
a=1#(3 points- For loop)
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("left",i),left100list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("left",i),left100list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm100l",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
a<-a+1
}
#rename everything
names(spm100l1)<- c("timee","X","LeftHeel1", "LeftMidfoot1", "LeftForefoot1",
              "LeftTotalForce1")
names(spm100l2)<- c("timee","X","LeftHeel2", "LeftMidfoot2", "LeftForefoot2",
              "LeftTotalForce2")
names(spm100l3)<- c("timee","X","LeftHeel3", "LeftMidfoot3", "LeftForefoot3",
              "LeftTotalForce3")
names(spm100l4)<- c("timee","X","LeftHeel4", "LeftMidfoot4", "LeftForefoot4",
              "LeftTotalForce4")
names(spm100l5)<- c("timee","X","LeftHeel5", "LeftMidfoot5", "LeftForefoot5",
              "LeftTotalForce5")
#110 SPM Left
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("left",i),left110list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("left",i),left110list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm110l",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm110l1)<- c("timee","X","LeftHeel1", "LeftMidfoot1", "LeftForefoot1",
                    "LeftTotalForce1")
names(spm110l2)<- c("timee","X","LeftHeel2", "LeftMidfoot2", "LeftForefoot2",
                    "LeftTotalForce2")
names(spm110l3)<- c("timee","X","LeftHeel3", "LeftMidfoot3", "LeftForefoot3",
                    "LeftTotalForce3")
names(spm110l4)<- c("timee","X","LeftHeel4", "LeftMidfoot4", "LeftForefoot4",
                    "LeftTotalForce4")
names(spm110l5)<- c("timee","X","LeftHeel5", "LeftMidfoot5", "LeftForefoot5",
                    "LeftTotalForce5")
#---
#120 SPM Left
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("left",i),left120list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("left",i),left120list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm120l",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm120l1)<- c("timee","X","LeftHeel1", "LeftMidfoot1", "LeftForefoot1",
                    "LeftTotalForce1")
names(spm120l2)<- c("timee","X","LeftHeel2", "LeftMidfoot2", "LeftForefoot2",
                    "LeftTotalForce2")
names(spm120l3)<- c("timee","X","LeftHeel3", "LeftMidfoot3", "LeftForefoot3",
                    "LeftTotalForce3")
names(spm120l4)<- c("timee","X","LeftHeel4", "LeftMidfoot4", "LeftForefoot4",
                    "LeftTotalForce4")
names(spm120l5)<- c("timee","X","LeftHeel5", "LeftMidfoot5", "LeftForefoot5",
                    "LeftTotalForce5")
#130 SPM Left
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("left",i),left130list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("left",i),left130list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm130l",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm130l1)<- c("timee","X","LeftHeel1", "LeftMidfoot1", "LeftForefoot1",
                    "LeftTotalForce1")
names(spm130l2)<- c("timee","X","LeftHeel2", "LeftMidfoot2", "LeftForefoot2",
                    "LeftTotalForce2")
names(spm130l3)<- c("timee","X","LeftHeel3", "LeftMidfoot3", "LeftForefoot3",
                    "LeftTotalForce3")
names(spm130l4)<- c("timee","X","LeftHeel4", "LeftMidfoot4", "LeftForefoot4",
                    "LeftTotalForce4")
names(spm130l5)<- c("timee","X","LeftHeel5", "LeftMidfoot5", "LeftForefoot5",
                    "LeftTotalForce5")
#100 SPM Right
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("right",i),right100list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("right",i),right100list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm100r",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm100r1)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce1")
names(spm100r2)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce2")
names(spm100r3)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce3")
names(spm100r4)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce4")
names(spm100r5)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce5")
#110 SPM Right
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("right",i),right110list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("right",i),right110list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm110r",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm110r1)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce1")
names(spm110r2)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce2")
names(spm110r3)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce3")
names(spm110r4)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce4")
names(spm110r5)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce5")
#120 SPM Right
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("right",i),right120list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("right",i),right120list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm120r",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm120r1)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce1")
names(spm120r2)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce2")
names(spm120r3)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce3")
names(spm120r4)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce4")
names(spm120r5)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce5")
#130 SPM Right
listcheck<-list()
firstcheck<-list()
a=1
for (i in 1:5) {
  CycleLength<- nrow(assign(paste0("right",i),right130list[[i]]))*.01
  firstcheck[[a]]<-assign(paste0("right",i),right130list[[i]])
  listcheck[[i]]<-list(assign(paste0("Timeinsec",i),seq(.01,CycleLength,.01)))
  assign(paste0("spm130r",i),value = cbind(as.vector(listcheck[[i]]),firstcheck[[a]])) 
  a<-a+1
}
#rename everything
names(spm130r1)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce1")
names(spm130r2)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce2")
names(spm130r3)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce3")
names(spm130r4)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce4")
names(spm130r5)<- c("timee","X","RightHeel1", "RightMidfoot1", "RightForefoot1",
                    "RightTotalForce5")

First set of graphs

The main purpose is just to be able to qualitatively look at the waveforms themselves, specifically how similar first and second peaks are and the slopes.

## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'

Put all the data together

I needed to use cbind.na since each of the waveforms may be different lengths. I used the apply function to get all the means and reshaped all that into a new table that fits my later analysis. I did this for both the means and the maxes.

#create a variable with all the total force data
alldataleft100<- qpcR:::cbind.na(spm100l1[6],spm100l2[6],spm100l3[6],spm100l4[6],spm100l5[6])
head(alldataleft100)
aveforces100<-apply(alldataleft100,2,mean,na.rm=TRUE)#Base of data frame (2 points- Apply)
head(aveforces100)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##        814.0044        838.2516        837.9572        834.6934        805.1296
#reshape (2 points- reshape)
lforcetable100 <- melt(aveforces100, # our data
        measure.vars=c("LeftTotalForce1","LeftTotalForce2","LeftTotalForce3",
                       "LeftTotalForce4","LeftTotalForce5"), 
        variable.name="Step",  
        value.name="Force"    
)


#aggregate then describe then use breaks on the graph (2 points aggregate)
sapply(alldataleft100,describe,na.rm=TRUE)#Good info could also be lapply
##          LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4
## vars     1               1               1               1              
## n        78              77              78              77             
## mean     814.0044        838.2516        837.9572        834.6934       
## sd       314.6573        302.4364        316.6412        291.6486       
## median   907.28          931.86          920.565         917.4          
## trimmed  856.0097        878.4051        877.1439        882.2968       
## mad      127.978         78.81502        110.9726        83.17386       
## min      29.4            42.96           26.3            29.64          
## max      1196.86         1232.4          1261.17         1153.44        
## range    1167.46         1189.44         1234.87         1123.8         
## skew     -1.355889       -1.378621       -1.305791       -1.585975      
## kurtosis 0.6638843       0.9851759       0.7410506       1.339833       
## se       35.62792        34.46582        35.85256        33.23644       
##          LeftTotalForce5
## vars     1              
## n        76             
## mean     805.1296       
## sd       295.4676       
## median   872.94         
## trimmed  840.5808       
## mad      124.7904       
## min      37.28          
## max      1222.48        
## range    1185.2         
## skew     -1.225259      
## kurtosis 0.7259215      
## se       33.89246
sapply(alldataleft100,max,na.rm=TRUE)#find maxes for each (should be first peak)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##         1196.86         1232.40         1261.17         1153.44         1222.48
#----
#create a variable with all the total force data
alldataleft110<- qpcR:::cbind.na(spm110l1[6],spm110l2[6],spm110l3[6],spm110l4[6],spm110l5[6])
head(alldataleft100)
aveforces110<-apply(alldataleft110,2,mean,na.rm=TRUE)#Base of data frame
head(aveforces110)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##        811.7621        792.9970        788.1965        808.3651        790.7163
#reshape
lforcetable110 <- melt(aveforces110, 
              measure.vars=c("LeftTotalForce1","LeftTotalForce2","LeftTotalForce3",
                            "LeftTotalForce4","LeftTotalForce5"), 
             variable.name="Step",  
             value.name="Force"    
)

#aggregate then describe then use breaks on the graph
sapply(alldataleft110,describe,na.rm=TRUE)#Good info could also be lapply
##          LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4
## vars     1               1               1               1              
## n        71              71              71              71             
## mean     811.7621        792.997         788.1965        808.3651       
## sd       323.9938        311.894         310.2024        321.3114       
## median   882.34          880.09          871.92          908.04         
## trimmed  849.3319        837.6274        829.49          848.9663       
## mad      169.6539        176.9187        169.2536        147.9931       
## min      30.36           28.98           30              34.77          
## max      1264.45         1172.48         1183.26         1226.16        
## range    1234.09         1143.5          1153.26         1191.39        
## skew     -1.09525        -1.239815       -1.19594        -1.1622        
## kurtosis 0.2909189       0.3830478       0.3432578       0.1969641      
## se       38.45099        37.01501        36.81426        38.13265       
##          LeftTotalForce5
## vars     1              
## n        71             
## mean     790.7163       
## sd       307.7261       
## median   879.06         
## trimmed  832.2207       
## mad      166.407        
## min      29.37          
## max      1178.1         
## range    1148.73        
## skew     -1.204518      
## kurtosis 0.3250981      
## se       36.52037
sapply(alldataleft110,max,na.rm=TRUE)#find maxes for each (should be first peak)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##         1264.45         1172.48         1183.26         1226.16         1178.10
#---
#create a variable with all the total force data
alldataleft120<- qpcR:::cbind.na(spm120l1[6],spm120l2[6],spm120l3[6],spm120l4[6],spm120l5[6])
head(alldataleft120)
aveforces120<-apply(alldataleft120,2,mean,na.rm=TRUE)#Base of data frame
head(aveforces120)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##        774.8794        749.9098        779.9093        777.5176        753.0646
#reshape
lforcetable120 <- melt(aveforces120, 
             measure.vars=c("LeftTotalForce1","LeftTotalForce2","LeftTotalForce3",
                            "LeftTotalForce4","LeftTotalForce5"), 
              variable.name="Step",  
              value.name="Force"    
)

#aggregate then describe then use breaks on teh graph
sapply(alldataleft120,describe,na.rm=TRUE)#Good info could also be lapply
##          LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4
## vars     1               1               1               1              
## n        67              65              67              68             
## mean     774.8794        749.9098        779.9093        777.5176       
## sd       312.5489        305.7865        310.8621        321.3536       
## median   855.1           850.42          858.69          872.275        
## trimmed  811.4525        789.8087        816.9696        813.662        
## mad      197.2451        167.7117        194.2206        153.9013       
## min      36              23.52           33.96           22.96          
## max      1159.68         1108.98         1168.12         1180.8         
## range    1123.68         1085.46         1134.16         1157.84        
## skew     -1.14848        -1.209867       -1.171235       -1.192992      
## kurtosis 0.1531566       0.2195751       0.2250702       0.2282887      
## se       38.18392        37.92814        37.97785        38.96984       
##          LeftTotalForce5
## vars     1              
## n        70             
## mean     753.0646       
## sd       343.5593       
## median   874.69         
## trimmed  792.915        
## mad      187.245        
## min      24.94          
## max      1175.64        
## range    1150.7         
## skew     -1.02514       
## kurtosis -0.3589164     
## se       41.06319
sapply(alldataleft120,max,na.rm=TRUE)#find maxes for each (should be first peak)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##         1159.68         1108.98         1168.12         1180.80         1175.64
#-
#create a variable with all the total force data
alldataleft130<- qpcR:::cbind.na(spm130l1[6],spm130l2[6],spm130l3[6],spm130l4[6],spm130l5[6])
head(alldataleft130)
aveforces130<-apply(alldataleft130,2,mean,na.rm=TRUE)#Base of data frame
head(aveforces130)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##        729.2513        735.2509        740.9426        759.4850        784.1110
#reshape
lforcetable130 <- melt(aveforces130,
              measure.vars=c("LeftTotalForce1","LeftTotalForce2","LeftTotalForce3",
                            "LeftTotalForce4","LeftTotalForce5"), 
              variable.name="Step",  
             value.name="Force"    
)

#aggregate then describe then use breaks on the graph
sapply(alldataleft130,describe,na.rm=TRUE)#Good info could also be lapply
##          LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4
## vars     1               1               1               1              
## n        62              64              65              64             
## mean     729.2513        735.2509        740.9426        759.485        
## sd       323.4696        324.3103        325.7353        323.1088       
## median   834.15          866.065         853.3           878.51         
## trimmed  764.0992        777.3606        778.3136        801.6044       
## mad      192.649         147.7337        196.4445        129.9351       
## min      20.58           25              22.14           21.06          
## max      1147.7          1093.07         1123.06         1130.78        
## range    1127.12         1068.07         1100.92         1109.72        
## skew     -0.9792441      -1.151426       -1.062635       -1.208204      
## kurtosis -0.3047226      -0.1488493      -0.2039797      0.0974081      
## se       41.08068        40.53879        40.40249        40.3886        
##          LeftTotalForce5
## vars     1              
## n        61             
## mean     784.111        
## sd       308.4293       
## median   886.5          
## trimmed  831.1943       
## mad      124.2715       
## min      30.88          
## max      1138.66        
## range    1107.78        
## skew     -1.34792       
## kurtosis 0.6182807      
## se       39.49032
sapply(alldataleft130,max,na.rm=TRUE)#find maxes for each (should be first peak)
## LeftTotalForce1 LeftTotalForce2 LeftTotalForce3 LeftTotalForce4 LeftTotalForce5 
##         1147.70         1093.07         1123.06         1130.78         1138.66
#----
#create a variable with all the total force data
alldataright100<- qpcR:::cbind.na(spm100r1[6],spm100r2[6],spm100r3[6],spm100r4[6],spm100r5[6])
head(alldataright100)
aveforcesr100<-apply(alldataright100,2,mean,na.rm=TRUE)#Base of data frame
head(aveforcesr100)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##         753.6280         797.2289         771.6980         820.4609 
## RightTotalForce5 
##         831.9099
#reshape
rforcetable100 <- melt(aveforcesr100, 
             measure.vars=c("RightTotalForce1","RightTotalForce2","RightTotalForce3",
                            "RightTotalForce4","RightTotalForce5"), 
              variable.name="Step",  
              value.name="Force"    
)

#aggregate then describe then use breaks on the graph
sapply(alldataright100,describe,na.rm=TRUE)#Good info could also be lapply
##          RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4
## vars     1                1                1                1               
## n        82               82               85               79              
## mean     753.628          797.2289         771.698          820.4609        
## sd       335.8591         350.2264         371.0091         322.3425        
## median   896.37           916.5            922.54           929.74          
## trimmed  805.1776         848.205          818.0974         869.3714        
## mad      124.8423         203.2645         192.1746         140.9804        
## min      4.08             21.89            21.12            24              
## max      1078.35          1159.78          1141.56          1152.21         
## range    1074.27          1137.89          1120.44          1128.21         
## skew     -1.270864        -1.20321         -1.111472        -1.453367       
## kurtosis 0.01285476       0.01716406       -0.3670893       0.7209503       
## se       37.08943         38.67603         40.24159         36.26637        
##          RightTotalForce5
## vars     1               
## n        78              
## mean     831.9099        
## sd       318.3615        
## median   933.24          
## trimmed  878.0252        
## mad      141.529         
## min      29.51           
## max      1198.92         
## range    1169.41         
## skew     -1.407374       
## kurtosis 0.7532469       
## se       36.04734
sapply(alldataright100,max,na.rm=TRUE)#find maxes for each (should be first peak)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##          1078.35          1159.78          1141.56          1152.21 
## RightTotalForce5 
##          1198.92
#------
#create a variable with all the total force data
alldataright110<- qpcR:::cbind.na(spm110r1[6],spm110r2[6],spm110r3[6],spm110r4[6],spm110r5[6])
head(alldataright110)
aveforcesr110<-apply(alldataright110,2,mean,na.rm=TRUE)#Base of data frame
head(aveforcesr110)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##         759.9618         784.6687         776.9873         751.9101 
## RightTotalForce5 
##         766.1709
#reshape
rforcetable110 <- melt(aveforcesr110, 
              measure.vars=c("RightTotalForce1","RightTotalForce2","RightTotalForce3",
                             "RightTotalForce4","RightTotalForce5"), 
              variable.name="Step",  
             value.name="Force"    
)

#aggregate then describe then use breaks on the graph
sapply(alldataright110,describe,na.rm=TRUE)#Good info could also be lapply
##          RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4
## vars     1                1                1                1               
## n        76               75               73               78              
## mean     759.9618         784.6687         776.9873         751.9101        
## sd       359.1293         323.1705         303.1072         315.0184        
## median   895.785          906.52           873.61           873.4           
## trimmed  803.4366         836.3689         827.8414         799.4944        
## mad      207.3564         165.3989         149.2385         149.6018        
## min      22.26            25.62            25.47            20              
## max      1124.01          1084.74          1074.6           1030.05         
## range    1101.75          1059.12          1049.13          1010.05         
## skew     -1.092674        -1.344556        -1.412058        -1.336916       
## kurtosis -0.3749179       0.3252876        0.5999207        0.2739863       
## se       41.19496         37.31652         35.47602         35.66882        
##          RightTotalForce5
## vars     1               
## n        76              
## mean     766.1709        
## sd       323.2115        
## median   878.52          
## trimmed  813.1329        
## mad      179.0091        
## min      21.9            
## max      1084.66         
## range    1062.76         
## skew     -1.263917       
## kurtosis 0.1532133       
## se       37.0749
sapply(alldataright110,max,na.rm=TRUE)#find maxes for each (should be first peak)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##          1124.01          1084.74          1074.60          1030.05 
## RightTotalForce5 
##          1084.66
#----
#create a variable with all the total force data
alldataright120<- qpcR:::cbind.na(spm120r1[6],spm120r2[6],spm120r3[6],spm120r4[6],spm120r5[6])
head(alldataright120)
aveforcesr120<-apply(alldataright120,2,mean,na.rm=TRUE)#Base of data frame
head(aveforcesr120)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##         694.7671         723.0069         743.9772         761.6057 
## RightTotalForce5 
##         738.8877
#reshape
rforcetable120 <- melt(aveforcesr120, # our data
              measure.vars=c("RightTotalForce1","RightTotalForce2","RightTotalForce3",
                            "RightTotalForce4","RightTotalForce5"), # The source columns (the columns we're combining)
             variable.name="Step",  # Name of the destination column that will identify the original  IV
              value.name="Force"    # column where the measurement values will be located  DV
)

#aggregate then describe then use breaks on the graph
sapply(alldataright120,describe,na.rm=TRUE)#Good info could also be lapply
##          RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4
## vars     1                1                1                1               
## n        72               71               71               70              
## mean     694.7671         723.0069         743.9772         761.6057        
## sd       337.8474         329.2689         310.4402         314.1729        
## median   818.675          834.33           850.65           857.5           
## trimmed  735.0359         767.287          794.4049         811.6521        
## mad      226.8749         205.8738         177.8379         208.9354        
## min      20               24.48            22.33            23.73           
## max      1039.35          1069.81          1031.7           1070.46         
## range    1019.35          1045.33          1009.37          1046.73         
## skew     -0.971744        -1.089933        -1.278608        -1.223399       
## kurtosis -0.5749888       -0.2875661       0.2009041        0.1776556       
## se       39.8157          39.07703         36.84247         37.55084        
##          RightTotalForce5
## vars     1               
## n        70              
## mean     738.8877        
## sd       334.5904        
## median   848.85          
## trimmed  786.845         
## mad      220.4849        
## min      20.32           
## max      1067.4          
## range    1047.08         
## skew     -1.112961       
## kurtosis -0.2484853      
## se       39.9912
sapply(alldataright120,max,na.rm=TRUE)#find maxes for each (should be first peak)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##          1039.35          1069.81          1031.70          1070.46 
## RightTotalForce5 
##          1067.40
#-----
#create a variable with all the total force data
alldataright130<- qpcR:::cbind.na(spm130r1[6],spm130r2[6],spm130r3[6],spm130r4[6],spm130r5[6])
head(alldataright130)
aveforcesr130<-apply(alldataright130,2,mean,na.rm=TRUE)#Base of data frame
head(aveforcesr130)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##         660.9980         718.0684         705.4901         692.1166 
## RightTotalForce5 
##         693.5103
#reshape
rforcetable130 <- melt(aveforcesr130, # our data
              measure.vars=c("RightTotalForce1","RightTotalForce2","RightTotalForce3",
                            "RightTotalForce4","RightTotalForce5"), 
             variable.name="Step",  
             value.name="Force"    
)

#aggregate then describe then use breaks on the graph
sapply(alldataright130,describe,na.rm=TRUE)#Good info could also be lapply
##          RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4
## vars     1                1                1                1               
## n        71               69               67               70              
## mean     660.998          718.0684         705.4901         692.1166        
## sd       366.831          361.7734         347.742          356.4685        
## median   811.44           863.27           842.24           832.245         
## trimmed  695.6035         752.7518         743.1965         727.8366        
## mad      249.4326         210.3216         203.472          192.5156        
## min      11.97            7.36             17.01            7.36            
## max      1029.6           1108.93          1050.92          1103.49         
## range    1017.63          1101.57          1033.91          1096.13         
## skew     -0.8204367       -0.9614745       -1.008916        -0.9019037      
## kurtosis -1.016178        -0.6698267       -0.5722025       -0.7467457      
## se       43.53483         43.5524          42.48345         42.60614        
##          RightTotalForce5
## vars     1               
## n        66              
## mean     693.5103        
## sd       352.6463        
## median   822.43          
## trimmed  727.4359        
## mad      244.0953        
## min      14.48           
## max      1077.12         
## range    1062.64         
## skew     -0.9225121      
## kurtosis -0.7008526      
## se       43.40776
sapply(alldataright130,max,na.rm=TRUE)#find maxes for each (should be first peak)
## RightTotalForce1 RightTotalForce2 RightTotalForce3 RightTotalForce4 
##          1029.60          1108.93          1050.92          1103.49 
## RightTotalForce5 
##          1077.12

Combine all cadences

I combined all the cadences for each leg first. Then I created factored columns for each of the limbs and an ordered column for cadence. Combine all those into dataframes with cadence, force, and limb, then make one master data frame that has both limbs.

#combine all the spm's
combinedleftforces<-rbind(lforcetable100,lforcetable110,lforcetable120,lforcetable130)
combinedrightforces<-rbind(rforcetable100,rforcetable110,rforcetable120,rforcetable130)

#create factored limb column
limb<- factor(rep("L",20))
head(limb)
## [1] L L L L L L
## Levels: L
rlimb<-factor(rep("R",20))
head(rlimb)
## [1] R R R R R R
## Levels: R
#create Factored cadence column
tempseq<-seq(100,130,10)#A sequence of 100 to 130 by 10
dupseq<-rep(tempseq,each=5)
Cadence<-ordered(dupseq) #(2 points-Ordering Data)
head(Cadence)
## [1] 100 100 100 100 100 110
## Levels: 100 < 110 < 120 < 130
levels(Cadence)
## [1] "100" "110" "120" "130"
#combine forces, cadence, and limb
combinedleftforcesprime<-cbind(Cadence,combinedleftforces,limb)
str(combinedleftforcesprime,20)
## 'data.frame':    20 obs. of  3 variables:
##  $ Cadence: Ord.factor w/ 4 levels "100"<"110"<"120"<..: 1 1 1 1 1 2 2 2 2 2 ...
##  $ Force  : num  814 838 838 835 805 ...
##  $ limb   : Factor w/ 1 level "L": 1 1 1 1 1 1 1 1 1 1 ...
head(combinedleftforcesprime)
combinedrightforcesprime<- cbind(Cadence,combinedrightforces,rlimb)
names(combinedrightforcesprime)<- c("Cadence","Force","limb")
head(combinedrightforcesprime)
#lastly combine both legs
bothlegforces<-rbind(combinedleftforcesprime,combinedrightforcesprime)
head(bothlegforces)
str(bothlegforces)
## 'data.frame':    40 obs. of  3 variables:
##  $ Cadence: Ord.factor w/ 4 levels "100"<"110"<"120"<..: 1 1 1 1 1 2 2 2 2 2 ...
##  $ Force  : num  814 838 838 835 805 ...
##  $ limb   : Factor w/ 2 levels "L","R": 1 1 1 1 1 1 1 1 1 1 ...

Make more relevant graphs

In this section I made lots of other graphs as well as made some new variables to analyze the different groups. I made barplots for mean and max force at each cadence by leg. Violin plots for each cadence and limb, scatter plots, and a boxplot.

#This graph is meant to compare avg left forces at each cadence
cadencemeansl<-tapply(combinedleftforcesprime$Force,combinedleftforcesprime$Cadence,mean)
head(cadencemeansl)
##      100      110      120      130 
## 826.0072 798.4074 767.0561 749.8082
coul <- brewer.pal(5, "Set2") #(2 Points- Rcolorbrewer)
lcadencebar<-barplot(cadencemeansl,beside = TRUE,
           xlab = "Cadence",ylab = "Force (N)",
           main = "Average Force by Cadence (Left)",
           col=coul,ylim = c(0,1000))

#This graph is meant to compare avg right forces at each cadence
cadencemeansr<-tapply(combinedrightforcesprime$Force,combinedrightforcesprime$Cadence,mean)
head(cadencemeansr)
##      100      110      120      130 
## 794.9851 767.9398 732.4489 694.0367
coull <- brewer.pal(5, "Set1") 
rcadencebar<-barplot(cadencemeansr,beside = TRUE,
                     xlab = "Cadence",ylab = "Force (N)",
                     main = "Average Force by Cadence (Right)",
                     col=coull,ylim = c(0,1000))

#This graph is meant to compare average force by limb
limbmean<-tapply(bothlegforces$Force,bothlegforces$limb,mean)
head(limbmean)
##        L        R 
## 785.3197 747.3526
limbmeanbar<-barplot(limbmean,beside=TRUE,
                     xlab="Limb",ylab="Force (N)",
                     main= "Average Force by Limb",
                     col=coul, ylim = c(0,1000))

#max average force for each limb
limbmax<-aggregate(Force~limb,data = bothlegforces,mean)
limbmax
#max average force for each cadence avg of both legs
cadencemaxbothleg<-aggregate(Force~Cadence,data = bothlegforces,max)
cadencemaxbothleg
# (Cell) Means of both Cadence and limb
cellavg<-tapply(bothlegforces$Force, list(bothlegforces$Cadence,bothlegforces$limb), mean)
head(cellavg)
##            L        R
## 100 826.0072 794.9851
## 110 798.4074 767.9398
## 120 767.0561 732.4489
## 130 749.8082 694.0367
# (Cell) Maxes of both Cadence and limb
cellmax<-tapply(bothlegforces$Force, list(bothlegforces$Cadence,bothlegforces$limb), max)
head(cellmax)
##            L        R
## 100 838.2516 831.9099
## 110 811.7621 784.6687
## 120 779.9093 761.6057
## 130 784.1110 718.0684
#check for skewness of individual variables (1 Point-Describe)
describe(bothlegforces)
#Violin plot of Force across both cadence and limb groups #(5 Points-Violin Plot)
ggplot(data = bothlegforces) + geom_violin(aes(x = Cadence, y = Force, fill = limb))+
  ggtitle("Violin Plot: Average Force (N) by Cadence and Limb")+ 
  ylab("Force (N)")+
  coord_cartesian(ylim=c(650,850))

#as separate plots
ggplot(data = bothlegforces) + geom_violin(aes(x = Cadence, y = Force, fill = limb))+
  facet_grid(Cadence~limb) +  xlab("Cadence")+ ylab("Force (N)") + 
  ggtitle("Violin Plot: Average Force (N) by Cadence and Limb")+
  coord_cartesian(ylim=c(650,850))

# Scatterplot of cadence predicting force #(8 Points-Scatterplot)
cadencescatter <- ggplot(data = bothlegforces, aes(x = Cadence, y = Force)) + geom_point()+
  xlab("Cadence")+ ylab("Force (N)") + ggtitle("Scatterplot: Average Force (N) by Cadence for Both Limbs")+
  coord_cartesian(ylim=c(650,850))
cadencescatter

# loess curve (3 Points-Loess)
cadencescatter + geom_line(data=bothlegforces,aes(x=Cadence,y=Force))+geom_smooth(method = "loess")
## `geom_smooth()` using formula = 'y ~ x'

#scatterplot of limb predicting force-----useless
limbscatter<- ggplot(data=bothlegforces,aes(x=limb,y=Force))+geom_line()
limbscatter

#Boxplot of cadence on both leg force (5 Points-Boxplot)
ggplot(bothlegforces)+ geom_boxplot(aes(x=Cadence,y=Force,fill=Cadence)) +
  xlab("Cadence")+ ylab("Force (N)") + ggtitle("Average Force (N) by Cadence for Both Limbs")+
  scale_fill_brewer(palette = "Dark2")+coord_cartesian(ylim=c(650,850))

ggplot(bothlegforces)+ geom_boxplot(aes(x=Cadence,y=Force,fill=limb)) +
  xlab("Cadence")+ ylab("Force (N)") + ggtitle("Average Force (N) by Cadence for By Limb")+
  scale_fill_brewer(palette = "Dark2")+coord_cartesian(ylim=c(650,850))

Stats

I ran a multiple regression with cadence and limb predicting force, allowing for the two to interact. I ran an anova and summary on that model to further examine it. I also plotted it’s effects. Then I checked for homogeneity and normality. Then I looked at some specific post hoc tests.

#multiple regression with cadence and limb on force (1 Point-General linear model)
allvariablelm<-lm(Force~Cadence*limb,data=bothlegforces)
Anova(allvariablelm,type = "III")
summary(allvariablelm)
## 
## Call:
## lm(formula = Force ~ Cadence * limb, data = bothlegforces)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -41.357 -12.500   0.859  11.634  36.925 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      785.320      4.596 170.858  < 2e-16 ***
## Cadence.L        -58.126      9.193  -6.323 4.27e-07 ***
## Cadence.Q          5.176      9.193   0.563    0.577    
## Cadence.C          3.992      9.193   0.434    0.667    
## limbR            -37.967      6.500  -5.841 1.72e-06 ***
## Cadence.L:limbR  -17.528     13.000  -1.348    0.187    
## Cadence.Q:limbR  -10.859     13.000  -0.835    0.410    
## Cadence.C:limbR   -2.757     13.000  -0.212    0.833    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 20.56 on 32 degrees of freedom
## Multiple R-squared:  0.8169, Adjusted R-squared:  0.7768 
## F-statistic: 20.39 on 7 and 32 DF,  p-value: 3.978e-10
#Effects plot of cadence and limb force w/conf int
plot(allEffects(allvariablelm),#(3 Points-Effects package)
     lines=list(multiline=TRUE), 
     confint=list(style = "bars"),ylim=c(650,850))

#look at heterogeneity of variance
plot(allvariablelm,which=1)

#look at normality of residuals
plot(allvariablelm,which=2)

#specific contrasts post hoc in cadence
pairs(emmeans(allvariablelm,~Cadence))
## NOTE: Results may be misleading due to involvement in interactions
##  contrast                estimate   SE df t.ratio p.value
##  Cadence100 - Cadence110     27.3 9.19 32   2.972  0.0272
##  Cadence100 - Cadence120     60.7 9.19 32   6.608  <.0001
##  Cadence100 - Cadence130     88.6 9.19 32   9.635  <.0001
##  Cadence110 - Cadence120     33.4 9.19 32   3.636  0.0051
##  Cadence110 - Cadence130     61.3 9.19 32   6.663  <.0001
##  Cadence120 - Cadence130     27.8 9.19 32   3.027  0.0238
## 
## Results are averaged over the levels of: limb 
## P value adjustment: tukey method for comparing a family of 4 estimates
#limb
pairs(emmeans(allvariablelm,~limb))
## NOTE: Results may be misleading due to involvement in interactions
##  contrast estimate  SE df t.ratio p.value
##  L - R          38 6.5 32   5.841  <.0001
## 
## Results are averaged over the levels of: Cadence
#both
pairs(emmeans(allvariablelm,~Cadence*limb))#too much
##  contrast                    estimate SE df t.ratio p.value
##  Cadence100 L - Cadence110 L   27.600 13 32   2.123  0.4226
##  Cadence100 L - Cadence120 L   58.951 13 32   4.535  0.0018
##  Cadence100 L - Cadence130 L   76.199 13 32   5.861  <.0001
##  Cadence100 L - Cadence100 R   31.022 13 32   2.386  0.2819
##  Cadence100 L - Cadence110 R   58.067 13 32   4.467  0.0021
##  Cadence100 L - Cadence120 R   93.558 13 32   7.197  <.0001
##  Cadence100 L - Cadence130 R  131.971 13 32  10.151  <.0001
##  Cadence110 L - Cadence120 L   31.351 13 32   2.412  0.2701
##  Cadence110 L - Cadence130 L   48.599 13 32   3.738  0.0148
##  Cadence110 L - Cadence100 R    3.422 13 32   0.263  1.0000
##  Cadence110 L - Cadence110 R   30.468 13 32   2.344  0.3025
##  Cadence110 L - Cadence120 R   65.958 13 32   5.074  0.0004
##  Cadence110 L - Cadence130 R  104.371 13 32   8.028  <.0001
##  Cadence120 L - Cadence130 L   17.248 13 32   1.327  0.8818
##  Cadence120 L - Cadence100 R  -27.929 13 32  -2.148  0.4077
##  Cadence120 L - Cadence110 R   -0.884 13 32  -0.068  1.0000
##  Cadence120 L - Cadence120 R   34.607 13 32   2.662  0.1716
##  Cadence120 L - Cadence130 R   73.019 13 32   5.617  0.0001
##  Cadence130 L - Cadence100 R  -45.177 13 32  -3.475  0.0285
##  Cadence130 L - Cadence110 R  -18.132 13 32  -1.395  0.8530
##  Cadence130 L - Cadence120 R   17.359 13 32   1.335  0.8784
##  Cadence130 L - Cadence130 R   55.771 13 32   4.290  0.0034
##  Cadence100 R - Cadence110 R   27.045 13 32   2.080  0.4480
##  Cadence100 R - Cadence120 R   62.536 13 32   4.810  0.0008
##  Cadence100 R - Cadence130 R  100.948 13 32   7.765  <.0001
##  Cadence110 R - Cadence120 R   35.491 13 32   2.730  0.1503
##  Cadence110 R - Cadence130 R   73.903 13 32   5.685  0.0001
##  Cadence120 R - Cadence130 R   38.412 13 32   2.955  0.0945
## 
## P value adjustment: tukey method for comparing a family of 8 estimates

Summary

Through looking at our graphs and tables, there is quite a lot going on in the data. The data showed a statistically significant difference between all cadence groups. There was a significant difference between limbs overall, but only at 130bpm controlling for cadence, though my right limb was always underloaded compared to my left. The most important finding of my preliminary search is that force decreases with increasing cadence at the same speed, with the difference notably increasing at 130bpm. In the literature when adults in my target population try to increase their speed, they increase their cadence up to 130, but I’m curious now if there may be changes beyond this. This will support my further research as I will be investigating these cadences over several gait speeds to evaluate changes in knee joint loading.