为dqr中的多个列设置`.names`,

f0brbegy  于 2023-10-13  发布在  其他
关注(0)|答案(1)|浏览(94)

背景:我尝试使用this solution的修改版本来创建跨多个变量的多个滞后列。该函数的关键部分是:

mutate(across(.cols = {{ var }}, .fns = map_lag, .names = "{.col}_lag{lags}"))

其中varlags是main函数的参数。
我发现对var使用单个列可以很好地工作,并为输出生成正确的.names,就像只为lags选择单个值一样(而不是一个范围,例如,1:5,但是将<tidy-select>列的集合作为varlags的范围进行馈送,不适用于当前的.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.
olhwl3o2

olhwl3o21#

mutate::across的帮助页面所述:
.names
描述如何命名输出列的粘合规范。这可以使用{.col}代表选定的列名,{.fn}代表正在应用的函数的名称。对于单个函数的情况,默认值(NULL)等效于“{.col}”,对于. fn使用列表的情况,则等效于“{.col}_{.fn}”。
在本例中,我们传递的是一个函数列表,因此它可以使用"{.col}_{.fn}"
因此,我们可以命名函数列表并使用"{.col}_lag{.fn}"

calculate_lags2 <- function(df, var, lags) {
  map_lag <- lags %>% map(~partial(lag, n = .x))
  names(map_lag) <- lags
  return(df %>% mutate(across(.cols = {{ var }}, .fns = map_lag, .names="{.col}_lag{.fn}")))
}

test  %>% calculate_lags2(x:y, 2:4)

       x     y x_lag2 x_lag3 x_lag4 y_lag2 y_lag3 y_lag4
   <int> <int>  <int>  <int>  <int>  <int>  <int>  <int>
 1     1    21     NA     NA     NA     NA     NA     NA
 2     2    22     NA     NA     NA     NA     NA     NA
 3     3    23      1     NA     NA     21     NA     NA
 4     4    24      2      1     NA     22     21     NA
 5     5    25      3      2      1     23     22     21
 6     6    26      4      3      2     24     23     22
 7     7    27      5      4      3     25     24     23
 8     8    28      6      5      4     26     25     24
 9     9    29      7      6      5     27     26     25
10    10    30      8      7      6     28     27     26

相关问题