mekevans / forestTIME

1 stars 0 forks source link

Filter on flexible arguments #13

Closed diazrenata closed 9 months ago

diazrenata commented 9 months ago

Maybe I'm not seeing something.

I would like to be able to pass duckdbfs a set of arguments and have it perform filter operations using those, without having to spell out in advance what all those arguments will be.

Like this:

my_filter_fxn <- filter(my_data, filter_criteria){
    filter(my_data, filter_criteria)
}

behaving something like

my_filter_fxn(my_data, filter_criteria = c("coat == 'calico'"))

returning all rows of my_data with coat==calico. This is easy to do if you know to expect certain args, but I don't know how to do it if you don't know in advance whether the function is going to be called to filter based on coat, or on whisker length, or whatever.

diazrenata commented 9 months ago

(It is also not impossible to do using bracket subsetting, but I want to do this using duckdbfs which to my knowledge works with dplyr syntax).

diazrenata commented 9 months ago

https://dplyr.tidyverse.org/articles/programming.html#transforming-user-supplied-variables

looks like you could parse something.

diazrenata commented 9 months ago

https://stackoverflow.com/questions/24569154/use-variable-names-in-functions-of-dplyr :eyes:

diazrenata commented 9 months ago
filter_on_passed_vars <- function(df, conditions = list("NYEARS == 2",
                                                        "TREE_UNIQUE_ID == 27_3_65_20067_3_19")) {

  splitcond = lapply(conditions, strsplit, split = " ") 

  call1 <- call(splitcond[[2]][[1]][2], as.name(splitcond[[2]][[1]][1]),
                                         (splitcond[[2]][[1]][3]))
  calls <- lapply(splitcond, FUN = function(a_split_condition)  call(a_split_condition[[1]][2], as.name(a_split_condition[[1]][1]),
                                                                     (a_split_condition[[1]][3])))

  df |>
    mutate_all(as.character()) |>
    filter(!!!calls)
}

This works but there is a warning about the !!! eval syntax.

....but I think that's OK? https://rlang.r-lib.org/reference/splice-operator.html

TBD if this works with duckdbfs tho. It works with dplyr but IDK about within duckdb.

(surely other ppl do this with sql calls, so there's also that route...)

diazrenata commented 9 months ago

I have this working. https://github.com/diazrenata/in-the-trees/blob/main/R/query_tables.R

diazrenata commented 8 months ago

@Aariq Here is where I had notes on passing variable and function names to filter, etc. Have at it!

Aariq commented 8 months ago

You can do this with rlang like so:

f4 <- function(...) {
  exprs <- rlang::enquos(...)
  iris |> 
    dplyr::filter(!!!exprs)
}

f4(Species == 'setosa', Petal.Width < 0.3, Sepal.Length == 5.1)
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          5.1         3.4          1.5         0.2  setosa
#> 3          5.1         3.8          1.6         0.2  setosa

Created on 2024-01-31 with reprex v2.0.2

Not sure how to get this working with a list as an input, only with ...

diazrenata commented 8 months ago

Cool, I'll see if this can work!

On Wed, Jan 31, 2024 at 4:43 PM Eric R. Scott @.***> wrote:

External Email

You can do this with rlang like so:

f4 <- function(...) { exprs <- rlang::enquos(...) iris |> dplyr::filter(!!!exprs) }

f4(Species == 'setosa', Petal.Width < 0.3, Sepal.Length == 5.1)#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species#> 1 5.1 3.5 1.4 0.2 setosa#> 2 5.1 3.4 1.5 0.2 setosa#> 3 5.1 3.8 1.6 0.2 setosa

Created on 2024-01-31 with reprex v2.0.2 https://reprex.tidyverse.org

Not sure how to get this working with a list as an input, only with ...

— Reply to this email directly, view it on GitHub https://github.com/mekevans/forestTIME/issues/13#issuecomment-1920187438, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEH6DN6UEVOPUZJDYR4LJYLYRLJLFAVCNFSM6AAAAABBTYE2I6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRQGE4DONBTHA . You are receiving this because you modified the open/close state.Message ID: @.***>