0
votes

Problem context: list returned need chr (character). Created function, fun_grade(), to conditionally select numeric value (as character) to return and update inside data frame. A list was returned in the data frame df_credit_status$grade field. Perhaps I needed to cast to as.character, or is there a better function method to change the character column?

list returned need simple chr

fun_grade <- function(grade) {
  if (grade == "A") return("100")
  if (grade == "B") return("80")
  if (grade == "C") return("60")
  if (grade == "D") return("40")
  if (grade == "D") return("20")
  if (grade == "F") return("10")
  return
}
df_credit_status$grade <- sapply(df_credit_status$grade, FUN=fun_grade)
2

2 Answers

3
votes

Instead of doing the multiple if conditions, use a named vector to replace the values.

setNames(c(100, 80, 60, 40, 20, 10),
              LETTERS[1:6])[as.character(df_credit_status$grade)]

Using a small reproducible example

set.seed(24)
v1 <- sample(LETTERS[1:6], 25, replace = TRUE)
setNames(c(100, 80, 60, 40, 20, 10), LETTERS[1:6])[v1]
#   C   B   C   E   B   F   B   A   D   A   A   E   E   A   E   E   D   E   B   A   D   C   E   B   A 
#  60  80  60  20  80  10  80 100  40 100 100  20  20 100  20  20  40  20  80 100  40  60  20  80 100 

Also, if/else is not vectorized, so either ifelse/if_else/case_when is needed (which would not be that efficient anyway)

3
votes

OK, I simulated a data frame:

df_credit_status <- data.frame(
  grade = sample(
    c("A", "B", "C", "D", "E", "F"), 
    size = 200, 
    replace = TRUE)
)

And modified your code:

fun_grade <- function(grade) {as
  if (grade == "A") { 
    return("100")
  } else if (grade == "B") {
    return("80")
  } else if (grade == "C") {
    return("60")
  } else if (grade == "D") {
    return("40")
  } else if (grade == "E") {
    return("20")
  } else if (grade == "F") {
    return("10")
  }
}

df_credit_status$equiv_grade <- sapply(df_credit_status$grade, 
                                       FUN = fun_grade)

And got:

> head(df_credit_status)
  grade equiv_grade
1     F          10
2     D          40
3     F          10
4     F          10
5     C          60
6     C          60

Personally, I will do it using the tidyverse libraries:

library(tidyverse)

df_credit_status <- data.frame(
  grade = sample(
    c("A", "B", "C", "D", "E", "F"), 
    size = 200, 
    replace = TRUE)
)


df_credit_status <- df_credit_status %>% 
  mutate(
    equiv_grade = case_when(
      grade == "A" ~ "100",
      grade == "B" ~ "80",
      grade == "C" ~ "60",
      grade == "D" ~ "40",
      grade == "E" ~ "20",
      grade == "F" ~ "10"
    )
  )
# change the equivalencies above to numbers if you need that

I am using a second column, so information from the original is not lost.

HTH