pdf("g10.pdf");options(width=64) #setwd("C:\\Users\\kolassa\\Class553") setwd("~/Taught1/960-553/Data")
# Block 1 #**********************************************************/ # Stuart (1953 Biometrika 40, 105-110), quoted by Stuart */ # (1955 Biometrika 42, 412-416), and Agresti (1983 Bio- */ # metrics 39(2) 505-510), present an ordinal categoriza- */ # tion of right and left eye vision of Royal Ordinance */ # female factory workers 1943-46. */ #*********************************************************/ eyes<-read.table("eyes.dat",col.names=c("r","l","count")) #*****************************************************/ # Tests of Symmetry */ #*****************************************************/ cat('\n Eyesight example: test symmetry \n') #R credits McNemar here, and not Bowker. (eyetab<-xtabs(count~r+l,data=eyes)) mcnemar.test(eyetab) #***********************************************************/ # Election data from 1997, 2001, 2005 for London boroughs */ # C=conservative, L=labor, LD=liberal democrat, RU=respect */ # union. From http://www.election.demon.co.uk/1997LB.html */ # RU was a small recent party most ideologically related to*/ # labor. */ #***********************************************************/ elections<-read.table("elections.dat", col.names=c("w97","w01","w05")) elections$w05c<-elections$w05 elections$w05c[elections$w05=="RU"]<-"L" parties<-unique(sort(as.matrix(elections))) elections$w97<-factor(elections$w97,levels=parties) elections$w01<-factor(elections$w01,levels=parties) elections$w05<-factor(elections$w05,levels=parties) elections$w05c<-factor(elections$w05c,levels=parties) elections cat('\n Electon example: test symmetry \n') #*************************************************************/ # With zero denominators, we have a problem. */ #*************************************************************/ (etab1<-xtabs(~w97+w05,data=elections)) mcnemar.test(etab1) (etab2<-xtabs(~w97+w05c,data=elections)) mcnemar.test(etab2) #*************************************************************/ # Fit the symmetry model via Poisson reg. Make covariates to*/ # represent diagonal entries, and covariates for each sym- */ # metry pair. If J=number of rows and columns, first J are */ # diagonal entries and next J*(J-1)/2 symmetry terms. Neg- */ # ative multiplier makes 0 the baseline category. */ #*************************************************************/ cat('\n Eye Symmetry via Poisson Regression \n') levs<-unique(c(eyes$r,eyes$l)) n<-length(levs) eyes$sym<-eyes$count; for(i in seq(n)) for(j in i:n){ eyes$sym[((eyes$r==levs[i])& (eyes$l==levs[j]))|((eyes$r==levs[j])& (eyes$l==levs[i]))]<-paste(levs[i],levs[j],sep="") } eyes #*************************************************************/ #Fit the Poisson model. Specify no main effects, so that the*/ #probabilities really are symmetric. Drop the intercept to */ #make the output cleaner. Examining fitted values verifies */ #that off-diagonal fits are the averages of the two counts. */ #*************************************************************/ symmetricfit<-glm(count~-1+factor(sym), data=eyes, family=poisson) symmetricfit fitted(symmetricfit) #*************************************************************/ #Fit the saturated model, and compare the log likelihoods. */ #Verify that the resulting test statistic is similar to */ #Bowker's test. Both have the same DF. */ #*************************************************************/ saturated<-glm(count~factor(paste(r,l))-1,data=eyes, family=poisson) summary(saturated) anova(symmetricfit,saturated) #Use the function estimable from the gmodels library to gen- #erate a Wald test for the contrasts. library(gmodels)#For estimable; Fits linear constraints to generalized linear models. #R has some built-in constrast matrices. Do ?contr.sum to #get a list of these; these do not include the ones we need. #I think I wrote the ones below based on contr.sum. This is #more than we need at present; it is of the general form #that R requires for fitting the contrasts internal to glm. contr.both<-function(n,scores=1:n,contrasts=FALSE, full=TRUE,sym=TRUE){ if (is.numeric(n) && length(n) == 1) levs <- 1:n else { levs <- n n <- length(levs) } rtn<-sqrt(n) contr<-if(!full){ array(0,c(n,(if(sym){rtn}else{rtn-2})*(rtn-1)/2)) }else{ array(0,c(n,n-1)) } count<-0 a<-if(sym){1}else{2} for(i in a:(rtn-1)) for(j in (i+1):rtn){ contr[(i-1)*rtn+j,count<-count+1]<-1 contr[(j-1)*rtn+i,count]<- -1 if(!sym){ contr[(1-1)*rtn+j,count]<- -1 contr[(i-1)*rtn+1,count]<- -1 contr[(1-1)*rtn+i,count]<- 1 contr[(j-1)*rtn+1,count]<- 1 } } if(full){ for(i in a:(rtn-1)) for(j in (i+1):rtn){ contr[(i-1)*rtn+j,count<-count+1]<-1 contr[(j-1)*rtn+i,count]<- 1 contr[(j-1)*rtn+j,count]<- -1 contr[(i-1)*rtn+i,count]<- -1 } for(i in 1:(rtn-1)){ contr[(i-1)*rtn+i,count<-count+1]<-1 contr[1,count]<- -1 } } return(contr) } contr.sym<-function(n,scores=1:n,contrasts=FALSE,full=TRUE){ return(contr.both(n,scores=scores,contrasts=contrasts, full=full,sym=TRUE))} contr.qsym<-function(n,scores=1:n,contrasts=FALSE,full=TRUE){ return(contr.both(n,scores=scores,contrasts=contrasts, full=full,sym=FALSE))} #Test symmetry. First, examing contrasts we use: t(contr.sym(16,full=F)) #I get a warning here that seems safe to ignore. estimable(saturated,t(contr.sym(16,full=F)),joint.test=T) # Block 2 #*****************************************************/ # Quasisymmetry */ #*****************************************************/ #Test quasi-symmetry: estimable(saturated,t(contr.qsym(16,full=F)),joint.test=T) # Block 3 # Marginal symmetry/homogeneity test. library(cta)#For mph.fit; Fits nonlinear constraints to contingency tables. # h.fct is a function of cell counts or proportions, and # defines contrasts among proportions corresponding to # marginal symmetry. M.fct also comes from library cta. # It examines the data frame and determines which entires # corresond to which explanatory variable levels. Marginal # symmetry then is equivalent to difference in sums over # similar categories being zero. h.fct<-function(p){ p.r<-M.fct(eyes$r)%*%p p.l<-M.fct(eyes$l)%*%p as.matrix(c(p.r[-4]-p.l[-4])) } # Note that this calculation really can't be written in # format where input data is written in a data= format. # Maybe this could have been done using attach, or with. mph.summary(mph.fit(y=eyes$count,h.fct=h.fct)) # Block 4 #**********************************************************/ #Test the quasi-independence model. Create a variable d */ # giving the row and column number for diagonal elements. */ # Use this variable as a factor. The baseline is 0, corr.*/ # to off-diagonal elements. Test this alt. hypothesis */ #HA vs. H0 of independence using Type 3 analysis. Test H0*/ #of quasi-independence vs. HA of the saturated model using*/ #the likelihood for HA above. */ #**********************************************************/ cat('\n Quasiindependence via poisson regression \n') eyes$d<-eyes$r*(eyes$r==eyes$l) quasiindfit<-glm(count~factor(r)+factor(l)+factor(d), data=eyes, family=poisson) summary(quasiindfit) #Test quasiindependence anova(saturated,quasiindfit) # Block 5 #*****************************************************/ # Polychoric Correlation. */ #*****************************************************/ cat('\n Polychoric Correlation \n') # Note subtle spelling difference between package and # function name. Estimator is not MLE unless you add # flag ML=TRUE. library(polycor)#For polychor; Calculates polychoric correlation. polychor(xtabs(count~r+l,data=eyes),std.err=TRUE, ML=TRUE)