'How to create a quiz score variable in R

I have a dataset in R similar to the following, where each row belongs to a person who has taken a quiz:

example <- tibble(ID = c(1,2,3),
                  age = c(12,12,11),
                  Q1 = c(T,T,T),
                  Q2 = c(F,F,T),
                  Q3 = c(F,T,F))
ID age Q1 Q2 Q3
1 12 TRUE FALSE FALSE
2 12 TRUE FALSE TRUE
3 11 TRUE TRUE FALSE

I want to score each person's quiz in a variable called "score". For example, if I know the correct answers are True for Q1, True for Q2, and and False for Q3, it should look like this:

ID age Q1 Q2 Q3 score
1 12 TRUE FALSE FALSE 66.7
2 12 TRUE FALSE TRUE 33.3
3 11 TRUE TRUE FALSE 100

What's the best way to do this in R over many questions (say 50), and other variables in the data set? I imagine we might want a row of the answer key and create a mean score based on equality of the rows?

r


Solution 1:[1]

correct <- c(T, T, F)

example %>%
  rowwise() %>%
  mutate(score = mean(unlist(c_across(Q1:Q3) == correct))*100)

     ID   age Q1    Q2    Q3    score
  <dbl> <dbl> <lgl> <lgl> <lgl> <dbl>
1     1    12 TRUE  FALSE FALSE  66.7
2     2    12 TRUE  FALSE TRUE   33.3
3     3    11 TRUE  TRUE  FALSE 100  


example %>%
  left_join(pivot_longer(.,-c(ID, age)) %>%
  group_by(ID) %>%
  summarise(score = 100 * mean(value == correct)))
     ID   age Q1    Q2    Q3    score
  <dbl> <dbl> <lgl> <lgl> <lgl> <dbl>
1     1    12 TRUE  FALSE FALSE  66.7
2     2    12 TRUE  FALSE TRUE   33.3
3     3    11 TRUE  TRUE  FALSE 100  

in base R:

cbind(example, score = colMeans(t(as.matrix(example[-(1:2)]))==correct) * 100)

  ID age   Q1    Q2    Q3     score
1  1  12 TRUE FALSE FALSE  66.66667
2  2  12 TRUE FALSE  TRUE  33.33333
3  3  11 TRUE  TRUE FALSE 100.00000

Solution 2:[2]

A possible base R solution:

correct <- c(T, T, F)

example$score <-
  rowMeans(t(apply(example[, 3:ncol(example)], 1, function(x)
    x == correct))) * 100

Output

     ID   age Q1    Q2    Q3    score
  <dbl> <dbl> <lgl> <lgl> <lgl> <dbl>
1     1    12 TRUE  FALSE FALSE  66.7
2     2    12 TRUE  FALSE TRUE   33.3
3     3    11 TRUE  TRUE  FALSE 100  

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 AndrewGB