Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
647 views
in Technique[技术] by (71.8m points)

r - Unquote the variable name on the right side of mutate function in dplyr

I am trying to make a function for a creating lagged variable using dplyr and function. But, the problem is that I cannot find how to unquote the variable name on the right side of mutate function.

mutate(dt,
    !!varname_t1 := !!varname_t0 # it does not work. 
)

Below is the real example of mine.

A. Here is the example data.

df <- tibble(
  a = sample(5)
)

# A tibble: 5 x 1
      a
  <int>
1     3
2     5
3     4
4     1
5     2

I want to make the data like this.

df <- df %>% mutate(a2 = lag(a1))

# A tibble: 5 x 2
     a1    a2
  <int> <int>
1     3    NA
2     1     3
3     5     1
4     2     5
5     4     2

B. I created a function but it does not work. I think the problem is this line. On the right side, I do not know how to unquote.

!!varname_t1 := !!varname_t0

My function is like this.

lag1_mutate <- function(dt, varname, time) { # time here is "after"

    # enquo 
    varname <- enquo(varname) 
    time1 <- enquo(time) 
    time0 <- time-1; time0 <- enquo(time0)

    # create the name of variables
    varname_t0 <- paste0(quo_name(varname), quo_name(time0)) 
    varname_t1 <- paste0(quo_name(varname), quo_name(time1))

    # check 
    print(varname_t0)
    print(varname_t1)

    # mutate        
    mutate(dt, 
        !!varname_t1 := !!varname_t0 # <-- problem, here
        # !!varname_t1 := lag(!!varname_t0) # produced only NAs
    )
}

The actual result is like this.

lag1_mutate(df, a, 2)

[1] "a1"
[1] "a2"
# A tibble: 5 x 2
      a    a2
  <int> <chr>
1     4    a1
2     1    a1
3     3    a1
4     2    a1
5     5    a1
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you have to convert the RHS string to a quosure, which you can do with sym from the rlang package. So use

mutate(dt, !!varname_t1 := lag(!!rlang::sym(varname_t0)))

Then your function will yield

lag1_mutate(df, a, 1)
# [1] "a0"
# [1] "a1"
# # A tibble: 5 x 2
#      a0    a1
#   <int> <int>
# 1     3    NA
# 2     4     3
# 3     1     4
# 4     5     1
# 5     2     5

(You set no seed, so my tibble values are different from yours.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...