Search code examples
rplyrscoring

Rescore Items from Scoring Key


I have a set of data on which respondents were given a series of questions, each with five response options (e.g., 1:5). Given those five options, I have a scoring key for each question, where some responses are worth full points (e.g., 2), others half points (1), and others no points (0). So, the data frame is n (people) x k (questions), and the scoring key is a k (questions) x m (responses) matrix.

What I am trying to do is to programmatically create a new dataset of the rescored items. Trivial dataset:

x <- sample(c(1:5), 50, replace = TRUE)
y <- sample(c(1:5), 50, replace = TRUE)
z <- sample(c(1:5), 50, replace = TRUE)
dat <- data.frame(cbind(x,y,z)) # 3 items, 50 observations (5 options per item)
head(dat)
  x y z
1 3 1 2
2 2 1 3
3 5 3 4
4 1 4 5
5 1 3 4
6 4 5 4

# Each option is scored 0, 1, or 2:
key <- matrix(sample(c(0,0,1,1,2), size = 15, replace = TRUE), ncol=5)
key
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    1    2
[2,]    2    1    1    1    2
[3,]    2    2    1    1    2

Solution

  • Some other options, firstly using Map:

    data.frame(Map( function(x,y)  key[y,x], dat, seq_along(dat) ))
    
    #  x y z
    #1 0 2 2
    #2 0 2 1
    #3 2 1 1
    #4 0 1 2
    #5 0 1 1
    #6 1 2 1
    

    Secondly using matrix indexing on key:

    newdat <- dat
    newdat[] <- key[cbind( as.vector(col(dat)), unlist(dat) )]
    newdat
    
    #  x y z
    #1 0 2 2
    #2 0 2 1
    #3 2 1 1
    #4 0 1 2
    #5 0 1 1
    #6 1 2 1
    

    Things would be even simpler if you specified key as a list:

    key <- list(x=c(0,0,0,1,2),y=c(2,1,1,1,2),z=c(2,2,1,1,2))
    data.frame(Map("[",key,dat))
    
    #  x y z
    #1 0 2 2
    #2 0 2 1
    #3 2 1 1
    #4 0 1 2
    #5 0 1 1
    #6 1 2 1