lundi 18 novembre 2019

pass only one argument to function from choice of a few and conditionally pipe within dplyr

I'm looking for a way to conditionally pass only one argument to a function (one of three choices). Based on the choice, I want to simply create a variable in the dataset. Lets say we have the following dataset:

set.seed(10)
test <- data.frame(time_stamp = sample(seq(as.Date('1999/01/01'), as.Date('2012/01/01'), by="day"), 12))
test
#    time_stamp
# 1  2000-05-05
# 2  2009-03-09
# 3  2008-04-24
# 4  2011-03-22
# 5  2003-05-27
# 6  2003-01-01
# 7  2008-10-22
# 8  2003-10-13
# 9  2011-02-26
# 10 2008-08-27
# 11 2011-12-30
# 12 2001-07-18

My desired output when I run my function is the following:

test_fun(type = "halfs") 
#or more simply
test_fun(halfs)
#    time_stamp half_var
# 1  2000-05-05  H1 2000
# 2  2009-03-09  H1 2009
# 3  2008-04-24  H1 2008
# 4  2011-03-22  H1 2011
# 5  2003-05-27  H1 2003
# 6  2003-01-01  H1 2003
# 7  2008-10-22  H2 2008
# 8  2003-10-13  H2 2003
# 9  2011-02-26  H1 2011
# 10 2008-08-27  H2 2008
# 11 2011-12-30  H2 2011
# 12 2001-07-18  H2 2001

Based on the argument chosen I run an if statement within a pipe, I thought I could do this if I put {} around the conditional statement as mentioned here, but I can't figure it out. Heres the function:

    test_fun <- function(type = c("halfs", "quarts", "other")) {
      test %>% {
        if (type == "halfs") {
          mutate(half_var = ifelse(month(time_stamp) <= 6, paste('H1', year(time_stamp)), paste('H2', year(time_stamp))))
        }  else if (type == "quarts") {
          mutate(quarts_var = case_when(month(time_stamp) <= 3 ~ paste('q1', year(time_stamp)), 
                                        month(time_stamp) > 3 & month(time_stamp) <= 6 ~ paste('q2', year(time_stamp)),
                                        month(time_stamp) > 6 & month(time_stamp) <= 9 ~ paste('q3', year(time_stamp)),
                                        month(time_stamp) > 9 ~ paste('q4', year(time_stamp))))
        }  else (type == "other") {
          mutate(other = ifelse(month(time_stamp) <= 6, paste('H1', year(time_stamp)), paste('H2', year(time_stamp))))
        }
      }

}

I'm getting an error about unexpected brackets but I think the problem is to do with conditional if within a pipe (all brackets are closed).

Another approach might be using optional argument as suggested here test_fun <- function(halfs, quarts = NULL, other = NULL)) but that way indicates that halfs must be supplied which is not the case. Really I want something like test_fun <- function(halfs = NULL, quarts = NULL, other = NULL)) or test_fun <- function(...)) which cant be done. A way around that might be to supply the data as an argument: test_fun <- function(test, halfs = NULL, quarts = NULL, other = NULL)) but I cant figure it out.

Any suggestions would be great.

Aucun commentaire:

Enregistrer un commentaire