背景:我尝试使用this solution的修改版本来创建跨多个变量的多个滞后列。该函数的关键部分是:
mutate(across(.cols = {{ var }}, .fns = map_lag, .names = "{.col}_lag{lags}"))
其中var
和lags
是main函数的参数。
我发现对var
使用单个列可以很好地工作,并为输出生成正确的.names
,就像只为lags
选择单个值一样(而不是一个范围,例如,1:5
,但是将<tidy-select>
列的集合作为var
和lags
的范围进行馈送,不适用于当前的.names
语法(但适用于函数的主要目的)。
从本质上讲,我认为问题归结为在across
中指定.names
,用于{.col}
和{lags}
的多个值。有没有办法指定.names
,使其正确扩展?
Reprex:
test <- tibble(x=1:10, y=21:30)
calculate_lags <- function(df, var, lags) {
map_lag <- lags %>% map(~partial(lag, n = .x))
return(df %>% mutate(across(.cols = {{ var }}, .fns = map_lag, .names = "{.col}_lag{lags}")))
}
## Works fine with just one variable and a range of lags
test %>% calculate_lags(x, 3:5)
# A tibble: 10 × 5
x y x_lag3 x_lag4 x_lag5
<int> <int> <int> <int> <int>
1 1 21 NA NA NA
2 2 22 NA NA NA
3 3 23 NA NA NA
4 4 24 1 NA NA
5 5 25 2 1 NA
6 6 26 3 2 1
7 7 27 4 3 2
8 8 28 5 4 3
9 9 29 6 5 4
10 10 30 7 6 5
## Or with multiple variables and a single value for lag
test %>% calculate_lags(x:y, 2)
# A tibble: 10 × 4
x y x_lag2 y_lag2
<int> <int> <int> <int>
1 1 21 NA NA
2 2 22 NA NA
3 3 23 1 21
4 4 24 2 22
5 5 25 3 23
6 6 26 4 24
7 7 27 5 25
8 8 28 6 26
9 9 29 7 27
10 10 30 8 28
## But not with multiple columns AND a range of lags
test %>% calculate_lags(x:y, 2:4)
> Error in `mutate()`:
> ℹ In argument: `across(.cols = x:y, .fns = map_lag, .names = "{.col}_lag{lags}")`.
> Caused by error:
> ! Variables must be length 1 or 6
> Run `rlang::last_trace()` to see where the error occurred.
1条答案
按热度按时间olhwl3o21#
如
mutate::across
的帮助页面所述:.names
描述如何命名输出列的粘合规范。这可以使用{.col}代表选定的列名,{.fn}代表正在应用的函数的名称。对于单个函数的情况,默认值(NULL)等效于“{.col}”,对于. fn使用列表的情况,则等效于“{.col}_{.fn}”。
在本例中,我们传递的是一个函数列表,因此它可以使用
"{.col}_{.fn}"
。因此,我们可以命名函数列表并使用
"{.col}_lag{.fn}"
: