Home > Blockchain >  vectorized inputs for if statements with several value changes (enabling a function to be used with
vectorized inputs for if statements with several value changes (enabling a function to be used with

Time:05-26

I am trying to apply a function from a package to certain columns of my dataframe. The package is linked here.

However, the author of the package used simple if statements, which won't let me use apply function, because of vectorized conditions. My problem is fixing this function specifically, so that I can use it in an apply function.

Mainly there are 4 if statements that need addressing:

1:

if (month < 1 | month > 12)
    stop("month is outside the range 1-12")
  if (day < 1 | day > 31)
    stop("day is outside the range 1-31")

2:

    if (month < 7)
      {
        days <- days   31 * (month -1 )
      } else{
        days <- days   186   30 * (month - 7)
      }

3:

if (days > 36524)
  {
    days <- days - 1
    gyear <- gyear   100 * (days %/% 36524)
    days <- days %% 36524
    if (days >= 365)
      days <- days   1
  }

4:

  if (days > 365)
  {
    gyear <- gyear   ((days - 1) %/% 365)
    days <- (days - 1) %% 365
  }

Now I know I can fix some of them with simple ifelse statements, but I have seen people avoiding assigning variables inside an ifelse statement and I prefer to use a general approach to fix this. Also, dplyr's case_when cannot be generally applied as well. Can anyone kindly help me solve this problem in a general relatively efficient way?

edit- As per MrFlick's comment, this is how I intend to use the function I have the original dates in my dataframe in months (summed as total months)

convert_date_to_greg <- function(x){
  year = floor(as.numeric(x)/12)
  month = (as.numeric(x)%) 1
  day = 1 
  ifelse(is.na(x)==FALSE,return(jal2greg(year,month,day,asDate = T)),return(NA))
}

greg_convert <- lapply(date_sorted_df[,date_column_indices],
                   FUN=convert_date_to_greg)

This is a sample input:

df<- data.frame(date_1=c(16735,16234,17123,16123), date_2=c(16352,16352,16666,17124))

However, using apply, I will see the following error message:

the condition has length > 1

CodePudding user response:

apply() type functions are for vectorized functions; they are not meant to be used with functions like this. You'll probably need to fix the function or use a solution other than apply().

I'd suggest fixing the function (R code should be vectorized when possible). For 1, you'll just want to check if any inputs are invalid. For 2-4, ifelse() will be helpful.

For 1:

if (sum(month < 1 | month > 12) != 0) { stop("a month is outside the range 1-12") }
if (sum(day < 1 | day > 31) != 0) { stop("a day is outside the range 1-31") }

For 2:

days <- ifelse(month < 7, days   31 * (month -1 ), days   186   30 * (month - 7))

For 3:

days <- days - 1
gyear <- gyear   100 * (days %/% 36524)
days <- days %% 36524
days <- ifelse(days >= 365, days <- days   1, days)     

For 4:

gyear <- ifelse(days > 365, gyear   ((days - 1) %/% 365, gyear)
days  <- ifelse(days > 365, (days - 1) %% 365, days)
  • Related