'In if (is.na(x)) { : condition has length and just first element will be used in R

I am trying to convert strings to date data class for specific columns in an specific df inside a list; As they come in excel format I am currently using excel_numeric_to_date from janitor package to convert them;

However when I apply the next code, I am running into lot of warnings and the output returns NA's instead of dates.

date_columns <- c("date1", "date2", "date3", "date4")



fun_excel_date <- function(x){
  if(is.na(x)){
    return(NA)
  } else {
    excel_numeric_to_date(as.numeric(
      as.character(x)
    ), date_system = "modern")
  }
}


df_list[["input_1"]][date_columns] <- lapply(
  df_list[["input_1"]][date_columns],
  fun_excel_date
)

Console output:

Warning messages:
1: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
2: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
3: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
4: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
5: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
6: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
7: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado
8: In if (is.na(x)) { :
  la condición tiene longitud > 1 y sólo el primer elemento será usado

Is there any other way to apply this function?



Solution 1:[1]

This is a common problem discussed in general here. For your specific code, the following should do what you expect:

if(length(x) == 1 && is.na(x)){
      return(NA)
} else {
...

Solution 2:[2]

The easiest way would be to just check where the string begins.

str_ = "..."
if not str_[2].isdigit():
    # basic
elif not str_[5].isdigit():
    # complex

Assuming that your strings always have 2 or 5 digits at the start, which seems to be the case based on your question.

Solution 3:[3]

Use a character group to catch all digits 0 to 9, and then use curly brackets to specify occurrences.

E.g.

[0-9]{3}

would catch 3 digits.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 scottkosty
Solution 2 Lucas
Solution 3 Joe Iddon