function declaring column names

Viewed 38

I have a function written in R. Basically I am applying a function to data frame column based on its values. Can anyone help me?.................................

asd <- data.frame(a = c("High Impact", "High Impact", "Medium Impact"),
                  b = c("High Impact", "No Impact", "High Impact"),
                  c = c("Low Impact", "No Impact", "Medium Impact"))

final_score <- function(q1,q2,q3){
  # ifelse(c == "A", "Low", "High")
  if (q1 == "Not Applicable") {
    q1_value = 0
  } else if (q1 == "No Impact") {
    q1_value = 0
  } else if (q1 == "Low Impact") {
    q1_value = 1
  } else if (q1 == "Medium Impact") {
    q1_value = 2
  } else if (q1 == "High Impact") {
    q1_value = 3
  }
  
  if (q2 == "Not Applicable") {
    q2_value = 0
  } else if (q2 == "No Impact") {
    q2_value = 0
  } else if (q2 == "Low Impact") {
    q2_value = 1
  } else if (q2 == "Medium Impact") {
    q2_value = 2
  } else if (q2 == "High Impact") {
    q2_value = 3
  }
  
  if (q3 == "Not Applicable") {
    q3_value = 0
  } else if (q3 == "No Impact") {
    q3_value = 0
  } else if (q3 == "Low Impact") {
    q3_value = 1
  } else if (q3 == "Medium Impact") {
    q3_value = 2
  } else if (q3 == "High Impact") {
    q3_value = 3
  }
  fs  = q1_value + q2_value + q3_value
  return(fs)
}

###Expected output
asd$new <- final_score(asd$a,asd$b,asd$c)
              a           b             c       new
1   High Impact High Impact    Low Impact       7
2   High Impact   No Impact     No Impact       3
3 Medium Impact High Impact Medium Impact       7

I have a function written in R. Basically I am applying a function to data frame column based on its values. Can anyone help me?.................................

3 Answers

In dplyr you can use case_when and across -

library(dplyr)

asd %>%
  mutate(new = rowSums(across(.fns = ~case_when(. %in% c("Not Applicable", "No Impact") ~ 0, 
                                  . =="Low Impact" ~ 1, 
                                  . == "Medium Impact" ~ 2, 
                                  . == "High Impact" ~ 3))))

#              a           b             c new
#1   High Impact High Impact    Low Impact   7
#2   High Impact   No Impact     No Impact   3
#3 Medium Impact High Impact Medium Impact   7

When you find yourself copying your code over and over again, think whether a loop or a function are the better answers. This is a proposal to do the computation without additional packages. However, recoding can be done even more simple with suitable packages. The recode function in car is just one worhtwhile proposal out of many.

# Your example data
asd <- data.frame(a = c("High Impact", "High Impact", "Medium Impact"),
                  b = c("High Impact", "No Impact", "High Impact"),
                  c = c("Low Impact", "No Impact", "Medium Impact"))


# a small function for one value:
score <- function(value){
  if (value == "Not Applicable") return(0)
  if (value == "No Impact") return(0)
  if (value == "Low Impact") return(1)
  if (value == "Medium Impact") return(2)
  if (value == "High Impact") return(3)
  return(NA)
}

# apply that small function to each value in asd

apply(asd, 1:2, score)

# rowSums are the sums of the rows...

asd$new <- rowSums(apply(asd, 1:2, score))

print(asd)

A base R option

asd$new <- rowSums(
  `dim<-`(
    as.integer(factor(
      as.matrix(asd),
      levels = c("Low Impact", "Medium Impact", "High Impact")
    )),
    dim(asd)
  ),
  na.rm = TRUE
)

gives

> asd
              a           b             c new
1   High Impact High Impact    Low Impact   7
2   High Impact   No Impact     No Impact   3
3 Medium Impact High Impact Medium Impact   7
Related