Home > Mobile >  exchange the day and month if some date is greater than other
exchange the day and month if some date is greater than other

Time:12-24

i want to replace day with month and vice versa. for example, i have admission and discharge date (if the admission is greater than discharge date) change the day to month and month to day( e.g, admission=04/11/2021 and discharge=13/4/2021 then change the admission into 11/04/2021)

ADMISSION DATE 04/11/2021 04/12/2021 04/10/2021 13/04/2021 13/04/2021 04/12/2021

DISCHARGE DATE 13/4/2021 13/4/2021 13/4/2021 13/4/2021 13/4/2021 13/4/2021

CodePudding user response:

You can try the following function. The code won't swap the day and the month if the day component is more than 12.

swap_day_month <- function(d1, d2) {
  # Function to swap the day and month of a given date (d1) if d1 > d2 AND results in a valid date
  
  # Extract date components
  dd <- format(d1, "%d")
  mm <- format(d1, "%m")
  yyyy <- format(d1, "%Y")
  
  # Only swap if d1 > d2 AND the day component of d1 is <= 12
  swap <- which(d1 > d2 & dd <= 12)
  d1_swapped <- d1[swap]
  
  for(i in seq_along(swap)) {
    d1_swapped[i] <- as.Date(paste(yyyy[swap[i]], dd[swap[i]], mm[swap[i]], sep="-"))
  }
  d1[swap] <- d1_swapped
  return(d1)
}

Call the function:

adm_swapped <- swap_day_month(adm, dsc)

Check

data.frame(adm, dsc, swapped=ifelse(adm!=adm_swapped, "*", ""), adm_swapped, los=dsc-adm_swapped)
          adm        dsc swapped adm_swapped       los
1  2021-11-25 2021-05-11          2021-11-25 -198 days
2  2021-11-09 2021-10-15       *  2021-09-11   34 days
3  2021-04-05 2021-01-09       *  2021-05-04 -115 days
4  2021-07-28 2021-12-18          2021-07-28  143 days
5  2021-12-17 2021-12-21          2021-12-17    4 days
6  2021-11-13 2021-12-20          2021-11-13   37 days
7  2021-11-11 2021-09-01          2021-11-11  -71 days
8  2021-09-03 2021-06-08       *  2021-03-09   91 days
9  2021-12-21 2021-11-12          2021-12-21  -39 days
10 2021-05-08 2021-04-05       *  2021-08-05 -122 days

I used the following contrived data:

d1 <- as.Date("2021-01-01")
d2 <- as.Date("2021-12-31")
n <- 10

set.seed(101)

random_dates <- function(d1, d2, n) {
  sample(seq(d1, d2, by=1), size=n)
}

adm <- random_dates(d1, d2, n)
dsc <- random_dates(d1, d2, n)

CodePudding user response:

Input should be shown in reproducible form as requested at the top of the tag page. I have done that for you this time in the Note at the end.

1) transform Now convert the dates to Date class so that they can be compared and then use the minimum for the ADMISSION_DATE and the maximum for the DISCHARGE_DATE. No packages are used.

fmt <- "%d/%m/%Y"
DF |>
  transform(ADMISSION_DATE = as.Date(ADMISSION_DATE, fmt),
            DISCHARGE_DATE = as.Date(DISCHARGE_DATE, fmt)) |> 
  transform(ADMISSION_DATE = pmin(ADMISSION_DATE, DISCHARGE_DATE),
            DISCHARGE_DATE = pmax(ADMISSION_DATE, DISCHARGE_DATE))

giving

  ADMISSION_DATE DISCHARGE_DATE
1     2021-04-13     2021-11-04
2     2021-04-13     2021-12-04
3     2021-04-13     2021-10-04
4     2021-04-13     2021-04-13
5     2021-04-13     2021-04-13
6     2021-04-13     2021-12-04

2) dplyr If we wanted to use dplyr we can't just replace transform with mutate because transform takes the right hand sides from the input whereas mutate operates sequentially. We would need to assign each date to other names in order not to overwrite them before taking the minimum and maximum. We have picked out the columns that end in _DATE in case there were additional columns in the real data.

library(dplyr)

fmt <- "%d/%m/%Y"
DF %>%
  mutate(across(ends_with("_DATE"), as.Date, format = fmt, .names = "{.col}2"),
         ADMISSION_DATE = Reduce(pmin, across(ends_with("_DATE2"))),
         DISCHARGE_DATE = Reduce(pmax, across(ends_with("_DATE2")))) %>%
  select(-ends_with("_DATE2"))

Note

ADMISSION_DATE <- c("04/11/2021", "04/12/2021", "04/10/2021", 
  "13/04/2021", "13/04/2021", "04/12/2021")

DISCHARGE_DATE <- c("13/4/2021", "13/4/2021", "13/4/2021", 
  "13/4/2021", "13/4/2021", "13/4/2021")

DF <- data.frame(ADMISSION_DATE, DISCHARGE_DATE)
  •  Tags:  
  • r
  • Related