Home > Blockchain >  Is there a way to feed arguments to a dplyr function using a string variable? What is this called?
Is there a way to feed arguments to a dplyr function using a string variable? What is this called?

Time:01-10

In R is there a way to feed arguments (?) to a function like this:

df <- data.frame( ID = c(10, 20),
              strand = c(1,-1),
              type = c("pos", "neg") )

test1 <- "strand == \"-1\""
test2 <- "type == \"pos\""

df %>% dplyr::filter(test1)
df %>% dplyr::filter(test2)

My ultimate goal is a function that will filter the df using one column or the other, depending on the users preference:

strand_or_type <- function(df, strand_or_type) { 
    df <- data.frame( ID = c(10, 20),
              strand = (1,-1),
              type = ("pos", "neg") )

    if(strand_or_type == "strand"){
       col <- "strand == \"-1\""
    } else if(strand_or_type == "type") {
       col <- "type == \"pos\""
    }

    df %>% dplyr::filter(col)
}

Maybe there is a better way to describe this, will update ASAP if there is. sorry.

CodePudding user response:

We may use parse_expr

library(dplyr)
df %>%
    dplyr::filter(eval(rlang::parse_expr(test1)))

As a function

strand_or_type <- function(df, strand_or_type) { 
    str1 <- switch(strand_or_type,
          strand = "strand == \"-1\"",
          type = "type == \"pos\"")
    df %>%
      filter(eval(rlang::parse_expr(str1)))

}

-testing

 strand_or_type(df, "strand")
  ID strand type
1 20     -1  neg
> strand_or_type(df, "type")
  ID strand type
1 10      1  pos

Or instead of creating a string and evaluating, we may do

strand_or_type <- function(df, strand_or_type) { 
       to_filter <- switch(strand_or_type,
                     strand = -1,
      type = "pos")
      df %>%
         filter(if_any(all_of(strand_or_type), ~ .x == to_filter))
}

-testing

> strand_or_type(df, "strand")
  ID strand type
1 20     -1  neg
> strand_or_type(df, "type")
  ID strand type
1 10      1  pos

CodePudding user response:

With filter_ you can pass a string.

strand_or_type <- function(df, strand_or_type) { 

  if(strand_or_type == "strand"){
    col <- "strand == \"-1\""
  } else if(strand_or_type == "type") {
    col <- "type == \"pos\""
  }
  
  dplyr::filter_(df,col)
}
  • Related