2017-09-09 31 views
3

我正在尝试使用dplyr和函数为创建滞后变量创建一个函数。但是,问题是我找不到如何取消变异函数右侧的变量名称。在dplyr中取消引用mutate函数右侧的变量名称

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

下面是我的一个真实例子。

A.以下是示例数据。

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

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

我想使这样的数据。

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.我创建了一个函数,但它不起作用。我认为问题是这条线。在右侧,我不知道如何取消引用。

!!varname_t1 := !!varname_t0 

我的功能是这样的。

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 
    ) 
} 

实际结果是这样的。

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 

回答

3

我认为你必须在RHS字符串转换为quosure,您可以用symrlang包做。因此,使用

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

然后你的函数将产生

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 

(您可以不种,所以我tibble值是与你的不同)。

+0

谢谢!基于你的回答,我创建了下面的循环来创建从2到10的滞后变量。但是,它不起作用。它只产生一个“ai”变量而不是“a2”变量,并给出错误。 为(i的C(2:10)){ DF < - lag1_mutate(DF,A,I) } – aasungh

+0

这工作'lag1_mutate < - 函数(DT,varname的,时间){varname_t0 < - paste0(替代(varname),time-1); varname_t1 < - paste0(substitute(varname),time); mutate(dt,!! varname_t1:= lag(!! rlang :: sym(varname_t0)))}'@aasungh – lukeA

+0

它工作得很好! :) – aasungh

相关问题