**TRinker's R Blog » R**, and kindly contributed to R-bloggers)

**This is Part II of a multi part blog on the paste2 function…**

In my first post on the `paste2`

function I promised a proof of a few practical uses. The first example I have comes from psychometrics and comes out of a need left behind by ltm’s factor.score function. You can fit a survey data set with an IRT model and the ltm package will allow you to figure out ability estimates for people achieving an exact combination of binary scores. So for instance on a 6 question test a person may have the following score:

item1 item2 item3 item4 item5 item6 0 0 1 1 1 0

…meaning they got questions 1 and 2 wrong, 3-5 correct and question 6 incorrect. A total score of 3. Now the IRT model says that that particular combination has a particular ability estimate and a person with 3 different correct responses may not have the same ability score. The problem is factor.score gives the estimates but doesn’t tell you the ability scores for specific observations in the data set.

**paste2 to the rescue!**

Solution: Create a function, based on paste2, that pastes together all the observations’ scores as well as the estimates from the factor.scores function used after fitting a 1PL or 2PL model. Now we have two character strings that look something like this: `"001110"`

Then we can easily use some slick indexing and we have a basic look up table of ability scores to assign to each observation. Here’s the script that does that:

######################## # THE ABILITY FUNCTION # ######################## ability <- function(dataset, items.index, fact.score, digits = 3, full = TRUE){ SD <- fact.score$score.dat nc <- ncol(SD) ncd <- ncol(dataset) IT <- SD[, -c((nc-4):nc)] SD$strata <- as.factor(paste2(IT)) #the 1st paste2 dataset$strata <- as.factor(paste2(dataset[, items.index])) #the 2nd paste2 key <- c(SD$z1);names(key) <- levels(SD$strata) DF <- transform(dataset, ability=round(key[strata], digits = digits)) DF$strata <- NULL if (full){ return(DF) } else { return(DF$ability) } } #=========================================================================== ############## # TRY IT OUT # ############## #This loads thepaste2function and a binary tests data set calleddatload(url("http://dl.dropbox.com/u/61803503/paste2demo1.RData")) library(ltm) ##################################################### # FIT A 1PL AND 2PL MODEL AND GET ABILITY ESTIMATES # ##################################################### mod.2PL <- ltm(dat[, -c(1, 22)]~z1) #fit a 2PL model (FS2PL <- ltm::factor.scores(mod.2PL)) #obtain the ability scores mod.1PLcon <- rasch(dat[, -c(1, 22)], #fit a 2PL model constraint = cbind(ncol(dat[, -c(1, 22)]) + 1, 1)) (FS1PLcon <- ltm::factor.scores(mod.1PLcon)) #obtain the ability scores ############## # HERE IT IS # ############## ############################################################################### # `dataset` - This is the original data set you fit the model to. # # May have variables other than items. # # # # `items.index` - This the item column numbers. Can be supplied with # # the colon operator as in 2:21 or as a vector with concate # # as in c(1, 2, 3, 4, 5, 6, 7, 8, 9, ..., 21) # # # # `fact.score` - This is the object you assigned the factor.score outcome to # ############################################################################### ability(dataset = dat, items.index = 2:21, fact.score = FS2PL) #for the 2PL (ab.1PL <- ability(dat, 2:21, FS1PLcon)) #for the 1PL head(ab.1PL) ###################################### # TO DO IT COMBINED; multiple models # ###################################### FSlist <- list(FS2PL, FS1PLcon) LIST <- lapply(FSlist, function(x) ability(dat, 2:21, x, full=F)) new2 <- data.frame(dat, do.call('cbind', LIST)) names(new2)[names(new2)%in%c("X1", "X2")] <- c("ability_2PL", "ability_1PL") head(new2)

*In part III of this series we’ll explore a few more practical uses of the paste2 function!*

Click here for a .txt version of this script used here

**leave a comment**for the author, please follow the link and comment on his blog:

**TRinker's R Blog » R**.

R-bloggers.com offers

**daily e-mail updates**about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...