LEGACY CONTENT. If you are looking for Voteview.com, PLEASE CLICK HERE

This site is an archived version of Voteview.com archived from University of Georgia on May 23, 2017. This point-in-time capture includes all files publicly linked on Voteview.com at that time. We provide access to this content as a service to ensure that past users of Voteview.com have access to historical files. This content will remain online until at least January 1st, 2018. UCLA provides no warranty or guarantee of access to these files.

Homework 11, POLS 8505: MEASUREMENT THEORY
Due 2 November 2011



  1. In this problem we are going to compare Optimal Classification, W-NOMINATE, and Simon Jackman's Ideal.

    Download the R program:

    #
    #  Run W-NOMINATE
    #                Here is what the call to w-nominate looks like
    resultw <- wnominate(hr, dims=2, minvotes=18, polarity=c(2,9))
    summary(resultw)
    #
    # length(result)
    # class(result)
    #     [1] "nomObject"
    # names(result)
    #     [1] "legislators" "rollcalls"   "dimensions"  "eigenvalues" "beta"       
    #     [6] "weights"     "fits"       
    # 
    # result$legislators
    # result$rollcalls
    # result$dimensions
    # result$eigenvalues
    # result$beta
    # result$weights
    # result$fits
    #
    #       Note the logic here -- this adjusts for the weights on the dimensions
    WEIGHT=(resultw$weights[2])/(resultw$weights[1])
    X1 <- resultw$legislators$coord1D
    X2 <- (resultw$legislators$coord2D)*WEIGHT
    #
    #                This gets rid of the NAs
    rankx <- ifelse(is.na(result1$legislators$rank),999,result1$legislators$rank)
    ocrank_wnom1stR <- cor(rankx[rankx!=999],X1[rankx!=999])  Calculate the Correlation
    #
    #  Call IDEAL
    #             Here is the call to Ideal
    result2 <- ideal(hr, d=1, store.item=TRUE)
    #
    #> length(result2)
    #[1] 9
    #> class(result2)
    #[1] "ideal"
    #> names(result2)
    #[1] "n"       "m"       "d"       "codes"   "x"       "beta"    "xbar"   
    #[8] "betabar" "call"   
    #>    The summary command reports very useful statistics
    #> summary(result2)
    1. Run the program and turn in all the plots that it produces.

    2. Report all the fits for OC and W-NOMINATE.

    3. Report summary(result), summary(resultw), and summary(result2).

  2. Repeat Question (1) only now with sen111kh.ord -- 111th U.S. Senate (be sure to adjust the calls to OC and W-NOMINATE so conservatives/Republicans are on the right/positive side of the first dimension).

  3. In this problem we are going to read a United Nations roll call STATA file into OC and run an analysis.

    Download the R program:

      oc_un_stata.r -- Program that runs OC on a roll call matrix contained in a STATA file.
        un31-33.dta -- U.N. Sessions 31 - 33 (1976-79) roll call data

    #    Here is how to read a STATA file with roll calls in it
    data.stata <- read.dta("c:/uga_course_homework_11/un31-33.dta")
    attach(data.stata,warn.conflicts = FALSE)
    colnames(data.stata)    					# Note the first three columns aren't votes
    rc.stata <- rollcall(data.stata[,-(1:3)], yea=1, nay=6,		# Format data as rollcall object
            missing=9,     This is from Simon Jackman's pscl package
            notInLegis=0,
    	legis.names=data.stata[,3],
            desc="UN 31 to 33",
    	vote.names=colnames(data.stata)[-(1:3)]) 
    #
    countrycode <- ccode  This is a variable in the STATA file that holds the country code
    #
    #  Call OC
    #
    #  Example:  1-Dim
    #
    result1 <- oc(rc.stata, dims=1, polarity=c(2))
    #  
    #  Example:  2-Dim
    #
    result <- oc(rc.stata, dims=2, polarity=c(2,9))
    summary(result)
    1. Run the program and report the fits for one and two dimensions.

    2. Turn in the plots that the program generates.

    3. Note that the plot is in black and white and the dimensions are not labeled. Use color to show some of the key blocs of nations and then use that to determine what the labels should be for the first and second dimensions. Turn in this cleaned up two-panel plot in color neatly formatted. If you do not have a color printer, e-mail me the two panel plot in color.

  4. In this problem we are going to try out the metric unfolding version of SMACOF ("Scaling by Maximizing a Convex Function" or "Scaling by Majorizing a Complicated Function") which is discussed in Chapter 8 of Borg and Groenen. We are going to apply it to the 1968 NES Candidate Feeling Thermometers.

    Download the R program:

    Here is the key section of code:

    #np <- length(T[,1])
    nq <- length(T[1,])
    #
    kkk <- rep(1,nq)  Here is how to remove those respondents who have fewer than 5 Thermometer responses
    xrow <- sapply(1:np,function(i) length(kkk[!is.na(T[i,])]))
    #                 the kkk[] vector is used as a "trick" to get a count of the number of "NA"s in a row
    #> !is.na(T[10,])
    #    Wallace    Humphrey       Nixon    McCarthy      Reagan Rockefeller 
    #       TRUE        TRUE        TRUE       FALSE       FALSE       FALSE 
    #    Johnson      Romney     Kennedy      Muskie       Agnew       LeMay 
    #       TRUE       FALSE        TRUE       FALSE       FALSE       FALSE 
    # 
    #> kkk
    # [1] 1 1 1 1 1 1 1 1 1 1 1 1
    #> length(kkk[!is.na(T[10,])])
    #[1] 5
    #> kkk[!is.na(T[10,])]
    #[1] 1 1 1 1 1
    #> length(kkk)
    #[1] 12
    #> sum(kkk[!is.na(T[10,])])
    #[1] 5
    #
    #  DELETE ROWS WITH LESS THAN 5 THERMOMETER RESPONSES
    #
    NA5 <- (xrow<5)  Simple TRUE/FALSE vector -- TRUE if fewer than 5 responses
    T <- T[!NA5,]    This drops the rows
    NOTVOTE <- NOTVOTE[!NA5]  VOTE and NOTVOTE are taken from the STATA file
    VOTE <- VOTE[!NA5]
    np <- length(VOTE)        Reset the Number of Respondents
    ndim <- 2
    #
    T <- (100-T)/50           Transform the data to distances
    TT <- T
    TT[is.na(TT)] <- mean(T,na.rm=TRUE)  Stick the matrix mean in the "NA" entries
    weightmat <- rep(1,np*nq)  Create a weight matrix = 0 if missing, = 1 if not missing
    dim(weightmat) <- c(np,nq)   This ensures that smacofRect does not use that entry
    weightmat[is.na(T)] <- 0
    result <- smacofRect(TT, ndim=2, weightmat, itmax=10000)  Here is the call
    #
    #  class(result)
    # [1] "smacofR"
    #  length(result)
    # [1] 14
    #  names(result)
    #  [1] "obsdiss"  "confdiss" "conf.row" "conf.col" "stress"   "spp.row" 
    #  [7] "spp.col"  "ndim"     "model"    "niter"    "nind"     "nobj"    
    # [13] "metric"   "call"    
    #
    TEIGHT <- as.numeric(TT)
    dim(TEIGHT) <- c(np,nq)
    zmetric2 <- result$conf.col       Extract the Respondent and Candidate Coordinates
    zmetric <- as.numeric(zmetric2)
    dim(zmetric) <- c(nq,ndim)
    xmetric2 <- result$conf.row
    xmetric <- as.numeric(xmetric2)
    dim(xmetric) <- c(np,ndim)
    sse1 <- 0.0
    sse2 <- 0.0
       for (i in 1:np) {
         for(j in 1:nq) {
          dist_i_j <- 0.0
           for( k in 1:ndim) {
    #
    #  Calculate distance between points
    #
           dist_i_j <- dist_i_j+ (xmetric[i,k]-zmetric[j,k])*(xmetric[i,k]-zmetric[j,k])
           }
          sse1 <- sse1 + ((TEIGHT[i,j]) - sqrt(dist_i_j))*((TEIGHT[i,j]) - sqrt(dist_i_j))
          sse2 <- sse2 + ((TEIGHT[i,j]) - sqrt(dist_i_j))*((TEIGHT[i,j]) - sqrt(dist_i_j))*weightmat[i,j]
         }                          Note the Difference between sse1 and sse2
       }
    # 
    # SETUP FOR TWO DIMENSIONAL PLOT
    #
    xmax <- max(abs(xmetric))
    zz <- c(xmetric[,1],xmetric[,2],VOTE,NOTVOTE)
    dim(zz) <- c(np,4)
    #windows()
    plot(zz[,1],zz[,2],type="n",asp=1,
           main="",
           xlab="",
           ylab="",
           xlim=c(-xmax,xmax),ylim=c(-xmax,xmax),cex=1.2,font=2)
    #
    # Main title
    mtext("Metric MDS of 1968 Thermometers\nNixon (blue), Humphrey (red), Wallace (black)",side=3,line=1.50,cex=1.2,font=2)
    # x-axis title
    mtext("Liberal - Conservative",side=1,line=2.75,cex=1.2)
    # y-axis title
    mtext("Social/Lifestyle Issues",side=2,line=2.5,cex=1.2)
    #
    points(zz[zz[,3] == 23,1],zz[zz[,3] == 23,2],pch='N',col="blue",font=2)
    points(zz[zz[,3] == 11,1],zz[zz[,3] == 11,2],pch='H',col="red",font=2)
    points(zz[zz[,3] == 34,1],zz[zz[,3] == 34,2],pch='W',col="black",font=2)
    #
    points(zmetric[,1],zmetric[,2],pch=16,col="red")
    text(zmetric[,1],zmetric[,2], junk, pos=namepos, col="purple",font=2)
    #
    1. Run the program and turn in the plot.

    2. Report result$stress, sse1, and sse2.

    3. Change the program so that 8 thermometers are required for a respondent to be included in the analysis. Report np, result$stress, sse1, and sse2, and turn in the plot.