Search code examples
rfor-loopdplyrlapplydifftime

Best way to create multiple time differences variables


I would like to create multiple variables to show the time differences from a variable (V0) for several variables. I would like the absolute difference (i.e., ignoring the sign of the difference). All my variables are in date format.

I have the below code, which works, but I imagine there is a neater/better way of doing this in fewer lines of code. I've tried a couple of things without much luck.

df$V1_timediff <- (abs(as.numeric(difftime(df$V0, df$V1, units = "days"))))

df$V2_timediff <- (abs(as.numeric(difftime(df$V0, df$V2, units = "days"))))

df$V3_timediff <- (abs(as.numeric(difftime(df$V0, df$V3, units = "days"))))

df$V4_timediff <- (abs(as.numeric(difftime(df$V0, df$V4, units = "days"))))

Solution

  • I'll demonstrate using mtcars. Since it doesn't have POSIXt objects, I'll use simple -; this should work for your case as well, no changes, so technically no need for difftime, the results should be identical. However, the premise of both solutions below will work if adapted to use difftime.

    dplyr

    library(dplyr)
    mtcars %>%
      mutate(across(vs:carb, list(timediff = ~ abs(as.numeric(cyl - ., units = "days"))))) %>%
      head()
    #                    mpg cyl disp  hp drat    wt  qsec vs am gear carb vs_timediff am_timediff gear_timediff carb_timediff
    # Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4           6           5             2             2
    # Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4           6           5             2             2
    # Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1           3           3             0             3
    # Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1           5           6             3             5
    # Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2           8           8             5             6
    # Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1           5           6             3             5
    

    base R

    tmp <- lapply(mtcars$cyl - subset(mtcars, select = vs:carb),
                  function(z) abs(as.numeric(z, units = "days")))
    names(tmp) <- paste0(names(tmp), "_timediff")
    head(cbind(mtcars, tmp))
    #                    mpg cyl disp  hp drat    wt  qsec vs am gear carb vs_timediff am_timediff gear_timediff carb_timediff
    # Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4           6           5             2             2
    # Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4           6           5             2             2
    # Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1           3           3             0             3
    # Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1           5           6             3             5
    # Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2           8           8             5             6
    # Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1           5           6             3             5