Check each value in first column against first vector element, each value in second column against second vector element, etc.

Hi, all.

I am trying to use tidyverse functions to create a function that applies a scoring key, for multiple-choice question (MCQ) data, to a tibble. I can apply the scoring key to each column, where each column is an MCQ on a test, but the output is always transposed! Any ideas about how to apply the key to a tibble and then return a tibble that isn't transposed in any funky way? Here's where I'm at so far.

key <- c("A", "B", "C", "C") # The answers to each MCQ below

df <- tibble(
  I1 = sample( LETTERS[1:4], 4, replace = T),
  I2 = sample( LETTERS[1:4], 4, replace = T),
  I3 = sample( LETTERS[1:4], 4, replace = T),
  I4 = sample( LETTERS[1:4], 4, replace = T)
)

df1 <- df %>% mutate_all(  # The scores end up transposed here
  function( x) {
    if_else( x == key, 1, 0)
  }
)

df1

mutate_all applies your function down column by column, to in effect do it by your rows, you would transpose before you mutate

df1 <-  as_tibble(t(df)) %>% mutate_all(
  function( x) {
    if_else( x == key, 1, 0)
  }
)

Thanks, Nirgrahamuk. I think I was misinterpreting what was going on when I applied mutate_all(). I would like to apply the key columnwise, but I would like values in the first column of the df checked against the first element in the key vector, values in the second column checked against the second element in the key vector, etc. Any ideas on how to do this?

Thanks for all the help! I think the following does what I was trying to do:


rescore <- function( df, key){
  
  apply_key <- function( x){
    if_else( x == key, 1, 0)
  }
  
  df1 <- as_tibble( t( apply( df, 1, apply_key)))
  
  names(df1) <- colnames(df)
  
  return(df1)
  
}

I think this is the most concise solution

library(tidyverse)

(key <- c("A", "B", "C", "C")) # The answers to each MCQ below

(df <- tibble(
  I1 = sample( LETTERS[1:4], 4, replace = T),
  I2 = sample( LETTERS[1:4], 4, replace = T),
  I3 = sample( LETTERS[1:4], 4, replace = T),
  I4 = sample( LETTERS[1:4], 4, replace = T)
))

#solution
map2_dfc(df,seq_along(df),
     ~as.numeric((.x==key[.y])))

Hi, Nir.

Thanks a bunch! Silly question here: What does the ~ do in the "~as.numeric(( .x == key [.y]))" bit?

Its a shorthand for making an anonymous function

map2_dfc(df,seq_along(df),
         function(x,y){as.numeric(x==key[y])})

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.