2
\$\begingroup\$

I love relation and function. And I would love to move afap from one to the other.

I've been looking for the function as.function.data.frame (or alike on tbl) but couldn't get it.

The bells and whistles are not yet present (test, check...)

## returns function
## In some way relation are function
## | p1 | p2 | p3 | value |
## f(p1, p2, p3) = value
## only if functionnal dependency applies
## for a given combination of parameter, value is unique

as.function.data.frame = 
  function(dt, fmla){

    require(dplyr)

    f = as.function(fmla)
    valx = body(f)


    ## enclose data
    f_env = new.env()
    assign('dt', dt, f_env)
    assign('valx', # later used to select the attribute
           f %>% body %>% as.character,
           f_env)
    environment(f) <- f_env

    ## the body
    body(f) <- quote(
      {
        ## the filter: easier to get it as a data.frame and later inner_join, than use the dplyr::filter. imho
        fltr = 
          as.list(match.call())[-1] %>% ## -1 because the call is enclosed and contains on to much element.
          as.data.frame

        fltr %>%
          inner_join(dt, by = names(fltr)) %>%
          select_(valx) %>% ## select_ because a need to evaluate
          unlist %>% unname ## we want value not table (value may be table...)
      }
    )

    return(f)
  }

a start of a test

library(testthat)
## test it
test_that("test the as.function.data.frame",
          {
            dt_test = 
              data.frame(
                par1 = c(1,1,0,0),
                par2 = c(1,0,1,0),
                val1 = 1:4,
                val2 = 5:8) 

            dt_fun1 = dt_test %>% as.function(par1 + par2 ~ val1)
            dt_fun2 = dt_test %>% as.function(par1 + par2 ~ val2)

            expect_equal(dt_fun1(1,0), 2)
            expect_equal(dt_fun2(0,0), 8)
          }
)

Three points:

  • Has this function been implemented in an other package? (base, dplyr...)
  • Is it an okay way to build the function?
  • as.list(match.call())[-1]: I am looking for a way to get it like as.list(match.call()) but without the [-1] I get the full function as first argument and then the one I want.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.