Error in if statement { : missing value where TRUE/FALSE needed

Dear community,

I happen to have an error in a if statement, but can't see where the problem is.
The goal is to replace some values by others.
Here is the code:

for (i in 1:nrow(e))
{
if (e[i,"EDULEVEL"]!=" ")
{
if (e[i,"EDULEVEL"]=="1ère" | e[i,"EDULEVEL"]=="1")
{
e$EDULEVEL_cor[i]=11
} else if (e[i,"EDULEVEL"]=="2nde" | e[i,"EDULEVEL"]=="2")
{
e$EDULEVEL_cor[i]=10
} else if (e[i,"EDULEVEL"]=="3ème")
{
e$EDULEVEL_cor[i]=9
} else if (e[i,"EDULEVEL"]=="4ème")
{
e$EDULEVEL_cor[i]=8
} else if (e[i,"EDULEVEL"]=="5ème")
{
e$EDULEVEL_cor[i]=7
} else if (e[i,"EDULEVEL"]=="BAC")
{
e$EDULEVEL_cor[i]=12
} else if (e[i,"EDULEVEL"]=="BAC+1")
{
e$EDULEVEL_cor[i]=13
} else if (e[i,"EDULEVEL"]=="BAC+2")
{
e$EDULEVEL_cor[i]=14
} else if (e[i,"EDULEVEL"]=="BAC+3")
{
e$EDULEVEL_cor[i]=15
} else if (e[i,"EDULEVEL"]=="18" | e[i,"EDULEVEL"]=="Aucun")
{
e$EDULEVEL_cor[i]=NA
} else if (e[i,"EDULEVEL"]=="BAC+4")
{
e$EDULEVEL_cor[i]=16
} else if (e[i,"EDULEVEL"]=="BAC+5")
{
e$EDULEVEL_cor[i]=17
} else if (e[i,"EDULEVEL"]=="BEP" | e[i,"EDULEVEL"]=="CAP")
{
e$EDULEVEL_cor[i]=11
} else if (e[i,"EDULEVEL"]=="CE1")
{
e$EDULEVEL_cor[i]=2
} else if (e[i,"EDULEVEL"]== "Certificat d'études" | e[i,"EDULEVEL"]=="CM2")
{
e$EDULEVEL_cor[i]=5
} else if (e[i,"EDULEVEL"]== "Doctorat")
{
e$EDULEVEL_cor[i]=20
}
}
}

-->

Error in if (e[i, "EDULEVEL"] != " ") { :
missing value where TRUE/FALSE needed

Thank you for your help

your data contains at least one NA value
this does not evaluate to TRUE or FALSE, so would potentially need to be caught and most often interpreted as false the shiny package has a useful function for that. shiny::isTruthy() you could copy its code as your own function and use it without a further dependency on shiny.

otherwise you can catch the value being NA and deal with it in many ways, one way is to set its value with something that wouldnt match anything you would search for. I show that example after the shiny one

example of the issue and how you might solve


x <- NA

if(x=="blah blah"){
  print(x)
} else {
  print("no")
}


if(shiny::isTruthy(x=="blah blah")){
  print(x)
} else {
  print("no")
}

if(is.na(x)){
  x<-"__XX__"  # something you are sure wont match anything
}

if(x=="blah blah"){
  print(x)
} else {
  print("no")
}

finally, you could do a lot to clean up your code by simple techniques. the complex phrase e[i,"EDULEVEL"] is repeated many times, why not assign it to a shorter name and refer to that , at least in the local scope

checkme <- e[i,"EDULEVEL"]
if(checkme){} # ... etc. etc 

you might also look into alternative ways to write extened if / else chains.
perhaps switch() would work.
perhaps dplyr::case_when()
finally it might even be a good idea to write your conditions as a table/data.frame and do a join to look up the appropriate match.

1 Like

I'd recommend creating a table with the respective variables and outcomes and then joining it to your table(s).

Reference Table Example

              EDULEVEL cor
1                    1  11
2                 1ère  11
3                    2  10
4                 2nde  10
5                 3ème   9
6                 4ème   8
7                 5ème   7
8                  BAC  12
9                BAC+1  13
10               BAC+2  14
11               BAC+3  15
12                  18  NA
13               Aucun  NA
14               BAC+4  16
15               BAC+5  17
16                 BEP  17
17                 CAP  11
18                 CE1   2
19 Certificat d'études   5
20                 CM2   5
21            Doctorat  20

This is an example made from the information provided.

# Reference table is used as the primary table we will be joining the information to.
r1 <- base::data.frame(
  EDULEVEL = c(
    "1", "1ère", "2", "2nde", "3ème", "4ème", "5ème", "BAC", "BAC+1","BAC+2",
    "BAC+3", "18", "Aucun", "BAC+4", "BAC+5", "BEP", "CAP", "CE1",
    "Certificat d'études", "CM2","Doctorat"
  ),
  cor = c(11, 11, 10, 10, 9, 8, 7, 12, 13, 14, 15, NA, NA, 16, 17, 17, 11, 2, 5, 5, 20)
)

# Second reference table with differing characteristics (EDULEVEL is unchanged)
r2 <- base::data.frame(
  EDULEVEL = c(
    "1", "1ère", "2", "2nde", "3ème", "4ème", "5ème", "BAC", "BAC+1","BAC+2",
    "BAC+3", "18", "Aucun", "BAC+4", "BAC+5", "BEP", "CAP", "CE1",
    "Certificat d'études", "CM2","Doctorat"
  ),
  cor = c(20, 2, 3, 1, 29, 8, 3, 112, 14, 14, NA, NA, NA, NA, 1, 1, 1, 2, 5, NA, 20)
)

# Joining of two tables (r1 and r2).
r3 <- base::merge(x = r1, y = r2, by = "EDULEVEL",  all = TRUE)
1 Like

Thank you very much for your answer and the time you took to help me. It works perfectly now, I changed the NA values into XX and it solved everything! Thank you so much for the other tips as well. This will help me improve my R practice ! Have a great day

Thank you so much, it is a great idea I can use as well, in order to simplify the way I do so next time. Thank you for your time and have a great day !

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.