1

I'm new with R and i have a problem, I have a data frame, and I want to apply this function to each element of column G3

fun_pass <- function(calif){
  if(calif >= 10){
    x <- 1
  }else{
    x <-0
  }
  return(x)
}

The problem is that the function only applies to the first element of the mat_data$G3 column and fills the new mat_data$pass column with that single value.

I use apply for this:

mat_data$pass <- apply(mat_data$G3,2,fun_pass(mat_data$G3))

The goal is to have a new column that tells me if the student passed the course or not.

Alo
  • 15
  • 6
  • Could you please `dput(mat_data)` in your console and paste the output in the question in order to help you. There are other ways to reach what you want! – Duck Sep 13 '20 at 18:02
  • Similar to https://stackoverflow.com/a/63857265/13513328? – Waldi Sep 13 '20 at 18:06

2 Answers2

1

The issue is with if/else which is not vectorized. If we change the function to ifelse, it would work. Another issue is that apply with MARGIN it expects a data.frame/matrix. Here, it is extracting a vector 'G3'

fun_pass <- function(calif) ifelse(calif >= 10, 1, 0)

Here we don't need ifelse also

fun_pass <- function(calif) as.integer(calif >= 10)

If it is a single column, use

mat_data$pass <- fun_pass(mat_data$G3)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • @Alo Yes, if you check the `fun_pass` I created, it is with `ifelse` instead of `if/else`. `if/else` expects a single element i.e. scalar of length 1 – akrun Sep 13 '20 at 18:13
  • @Alo I think you are using your own function with `if/else`. If you change it to the function I showed, it would not give that warning – akrun Sep 13 '20 at 18:15
0

Try:

mat_data$pass <- sapply(X = mat_data$G3, FUN  = fun_pass)

test:

mat_data <- data.frame(G3 = 1:20)
mat_data$pass <- sapply(X = mat_data$G3, FUN  = fun_pass)

mat_data

#     G3 pass
# 1   1    0
# 2   2    0
# 3   3    0
# 4   4    0
# 5   5    0
# 6   6    0
# 7   7    0
# 8   8    0
# 9   9    0
# 10 10    1
# 11 11    1
# 12 12    1
# 13 13    1
# 14 14    1
# 15 15    1
# 16 16    1
# 17 17    1
# 18 18    1
# 19 19    1
# 20 20    1

Liman
  • 1,270
  • 6
  • 12