r-使用为mutate生成的函数列表(跨vs变异_at



我正在研究这个答案,它描述了mutate_at的使用,并提供了应用于列的函数列表。我已经修改了答案中的代码,并有一个工作示例,它似乎产生了我想要的数量(变量在不同时间间隔内的增长率(:

library(tidyverse)
set.seed(1)
## data
df <- data.frame(t = 1:10, y = runif(10))
lags <- c(1, 3, 5)
df %>% mutate_at(vars(y), .funs = {
map(lags, function(i) ~ (.x - lag(.x, n = i)) / lag(.x, n = i)) %>%
setNames(sprintf("growth_%1i", lags))
})
#     t          y    growth_1    growth_3   growth_5
# 1   1 0.26550866          NA          NA         NA
# 2   2 0.37212390  0.40155088          NA         NA
# 3   3 0.57285336  0.53941567          NA         NA
# 4   4 0.90820779  0.58541059  2.42063336         NA
# 5   5 0.20168193 -0.77793415 -0.45802478         NA
# 6   6 0.89838968  3.45448772  0.56827164  2.3836549
# 7   7 0.94467527  0.05152061  0.04015323  1.5386041
# 8   8 0.66079779 -0.30050271  2.27643527  0.1535200
# 9   9 0.62911404 -0.04794772 -0.29973145 -0.3073016
# 10 10 0.06178627 -0.90178844 -0.93459523 -0.6936450

但是,由于mutate_at已经被across语法所取代,并且为了与我的代码的其余部分保持一致,我一直在尝试使用新语法获得一个有效的版本。我有一些代码在运行,但似乎没有产生新的列,我也不知道为什么。


df %>% mutate(across(y, .funs = {
map(lags, function(i) ~ (.x - lag(.x, n = i)) / lag(.x, n = i)) %>%
setNames(sprintf("growth_%1i", lags))
}))
#     t          y
# 1   1 0.26550866
# 2   2 0.37212390
# 3   3 0.57285336
# 4   4 0.90820779
# 5   5 0.20168193
# 6   6 0.89838968
# 7   7 0.94467527
# 8   8 0.66079779
# 9   9 0.62911404
# 10 10 0.06178627

我之前曾尝试在mutate调用之外生成函数列表,但无法使其工作。我认为当前代码的问题可能是括号/大括号等的位置。但调整这些并没有解决问题。任何见解都将不胜感激。

在外部执行此操作,然后与原始数据绑定,而不是在across中创建列表或tibble对象,然后在unnest中使用

library(purrr)
library(stringr)
library(dplyr)
map_dfc(lags, ~ df %>% 
transmute(!! str_c('growth_', .x) := (y - lag(y, n = .x))/lag(y, n = .x))) %>%
bind_cols(df, .)

-输出

t         y   growth_1   growth_3   growth_5
1   1 0.8696908         NA         NA         NA
2   2 0.3403490 -0.6086552         NA         NA
3   3 0.4820801  0.4164288         NA         NA
4   4 0.5995658  0.2437058 -0.3105989         NA
5   5 0.4935413 -0.1768355  0.4501036         NA
6   6 0.1862176 -0.6226910 -0.6137206 -0.7858807
7   7 0.8273733  3.4430457  0.3799541  1.4309557
8   8 0.6684667 -0.1920615  0.3544292  0.3866300
9   9 0.7942399  0.1881517  3.2651170  0.3246917
10 10 0.1079436 -0.8640919 -0.8695346 -0.7812876

如果我们想使用across

library(tidyr)
df %>%
mutate(across(y,  function(.x) 
map_dfc(lags, function(i)  (.x - lag(.x, i))/(lag(.x, i))), 
.names = "growth")) %>% 
unnest(growth, names_sep = "_") %>%
rename_with(~ str_c('growth_', lags), starts_with('growth'))

-输出

# A tibble: 10 × 5
t     y growth_1 growth_3 growth_5
<int> <dbl>    <dbl>    <dbl>    <dbl>
1     1 0.870   NA       NA       NA    
2     2 0.340   -0.609   NA       NA    
3     3 0.482    0.416   NA       NA    
4     4 0.600    0.244   -0.311   NA    
5     5 0.494   -0.177    0.450   NA    
6     6 0.186   -0.623   -0.614   -0.786
7     7 0.827    3.44     0.380    1.43 
8     8 0.668   -0.192    0.354    0.387
9     9 0.794    0.188    3.27     0.325
10    10 0.108   -0.864   -0.870   -0.781

最新更新