0

I am new to R and a function that creates the first difference at different lag values (see code below).

dt %>%
        arrange(GEO, LF.char, NAICS, new_date) %>%
        mutate(fd = VALUE -lag(VALUE), FD_percent = fd/lag(VALUE),
            fd3 = VALUE -lag(VALUE, 3), FD_percent3 = fd3/lag(VALUE,3)) 

I am trying to create something like:

dt %>%
  arrange(GEO, LF.char, NAICS, new_date) %>%
  mutate_FD()

My attempt at writing the function was

mutate_FD <- function(x){
  mutate(fd = x.VALUE -lag(x.VALUE), FD_percent = fd/lag(x.VALUE),
         fd3 = x.VALUE -lag(x.VALUE, 3), FD_percent3 = fd3/lag(x.VALUE,3)) 
}

but i get the following error

Error in mutate(fd = x.VALUE - lag(x.VALUE), FD_percent = fd/lag(x.VALUE), : object 'x.VALUE' not found Called from: mutate(fd = x.VALUE - lag(x.VALUE), FD_percent = fd/lag(x.VALUE), fd3 = x.VALUE - lag(x.VALUE, 3), FD_percent3 = fd3/lag(x.VALUE, 3))

Can someone explain to me what I am doing wrong?

Jrakru56
  • 929
  • 5
  • 14
  • 1
    You need to share the dataframe you are working with. Share the output of `dput(head(dt))` and also the expected output. – Shree Oct 16 '18 at 19:43

1 Answers1

0

Programming with dplyr now uses a system nicknamed "tidyeval," which controls when a variable is "evaluated" vs. when it is "quoted."

https://dplyr.tidyverse.org/articles/programming.html

Here are some "recipes" that get straight to applications: https://edwinth.github.io/blog/dplyr-recipes/

To use tidyeval here, you'd need your function to specify which column to operate on. Then two steps:

  1. convert the name to a "quosure" using enquo. I don't understand the technical details yet, but my working mental model is that this is like putting your parameters into a "pill" so it can be safely swallowed by your function and activated (i.e. evaluated) later.

  2. use !! to unquote the quosure.

Here's how that could look for your function:

mutate_FD <- function(x, val_col){
  val_quo = enquo(val_col)
  x %>%
    mutate(fd = !!val_quo -lag(!!val_quo), 
           FD_percent = fd/lag(!!val_quo),
           fd3 = !!val_quo -lag(!!val_quo, 3), 
           FD_percent3 = fd3/lag(!!val_quo,3)) 
}

In the future, it would be yet more helpful if you could provide some sample data with your question. Lacking that, here's an example:

# Sample data
dt <- data.frame(GEO = runif(10, min = 0, max = 1000) %>% floor(),
                 value = runif(10, min = 0, max = 10) %>% floor())

# Using the function on the "dt" table, applying the function to the "value" column.
dt %>%
  mutate_FD(value)

   GEO value fd FD_percent fd3 FD_percent3
1  354     2 NA         NA  NA          NA
2  158     2  0  0.0000000  NA          NA
3  626     8  6  3.0000000  NA          NA
4  447     7 -1 -0.1250000   5   2.5000000
5  926     5 -2 -0.2857143   3   1.5000000
6  105     6  1  0.2000000  -2  -0.2500000
7  290     1 -5 -0.8333333  -6  -0.8571429
8  668     7  6  6.0000000   2   0.4000000
9  263     9  2  0.2857143   3   0.5000000
10 733     2 -7 -0.7777778   1   1.0000000
Jon Spring
  • 28,537
  • 3
  • 24
  • 43