[英]dplyr::mutate_if - Using created variables to build new ones
我正在使用mutate_if
修改工作區中某些數據框的列。 僅使用mutate
時,我可以根據預先創建的變量創建變量,例如
x %>%
mutate(new = column_a * 2,
new_2 = new * 2)
但是這種方法不適用於mutate_if
所以我必須制作某種“遞歸方法”,從“開始”創建每個變量,例如
mutate_if(!str_detect(names(.), 'date|PIB|Deflator|[$]'),
.funs = list(Real = ~ . / Deflator,
Real_YoY = ~ (((. / Deflator) / lag((. / Deflator), 12))-1) * 100))
所需的 output 是這樣的:
mutate_if(!str_detect(names(.), 'date|PIB|Deflator|[$]'),
.funs = list(Real = ~ . / Deflator,
Real_YoY = ~ ((Real / lag(Real, 12))-1) * 100))
有沒有辦法組織代碼來接近這個? 謝謝!
可重現的例子:
x <- data.frame(x = seq(1,10),
x1 = seq(21,30),
y = seq(10,19))
x %>% mutate_if(str_detect(colnames(.), 'x'),
.funs = list(new = ~ (. * 2),
new2 = ~ (. * 2) * 4)) # where (. * 2) could make reference to the variable 'new'
代替list
,返回一個tibble
,它也可以從其名稱中獲取上一個列值,然后取消tibble
unnest
library(dplyr)
library(tidyr)
x %>%
mutate(across(starts_with('x'),
~ tibble(`1` = (.x * 2),
`2` = `1` * 4), .names = "{.col}_new")) %>%
unnest(where(is.tibble), names_sep = "")
-輸出
# A tibble: 10 × 7
x x1 y x_new1 x_new2 x1_new1 x1_new2
<int> <int> <int> <dbl> <dbl> <dbl> <dbl>
1 1 21 10 2 8 42 168
2 2 22 11 4 16 44 176
3 3 23 12 6 24 46 184
4 4 24 13 8 32 48 192
5 5 25 14 10 40 50 200
6 6 26 15 12 48 52 208
7 7 27 16 14 56 54 216
8 8 28 17 16 64 56 224
9 9 29 18 18 72 58 232
10 10 30 19 20 80 60 240
或者也可以在轉換為tibble
后使用mutate
x %>%
transmute(across(starts_with('x'), ~ tibble(new1 = .x *2) %>%
mutate(new2 = new1 *4))) %>%
unnest(where(is_tibble), names_sep = "_") %>%
bind_cols(x, .)
-輸出
x x1 y x_new1 x_new2 x1_new1 x1_new2
1 1 21 10 2 8 42 168
2 2 22 11 4 16 44 176
3 3 23 12 6 24 46 184
4 4 24 13 8 32 48 192
5 5 25 14 10 40 50 200
6 6 26 15 12 48 52 208
7 7 27 16 14 56 54 216
8 8 28 17 16 64 56 224
9 9 29 18 18 72 58 232
10 10 30 19 20 80 60 240
或阻止{}
中的多個語句
x %>%
mutate(across(starts_with('x'), ~
{
new <- .x * 2
new2 <- new * 4
tibble(new, new2)}, .names = "{.col}_")) %>%
unnest(where(is_tibble), names_sep = "")
# A tibble: 10 × 7
x x1 y x_new x_new2 x1_new x1_new2
<int> <int> <int> <dbl> <dbl> <dbl> <dbl>
1 1 21 10 2 8 42 168
2 2 22 11 4 16 44 176
3 3 23 12 6 24 46 184
4 4 24 13 8 32 48 192
5 5 25 14 10 40 50 200
6 6 26 15 12 48 52 208
7 7 27 16 14 56 54 216
8 8 28 17 16 64 56 224
9 9 29 18 18 72 58 232
10 10 30 19 20 80 60 240
您需要在兩個 mutate 調用中執行此操作。 across
它不知道新列。 例如,即使您嘗試使用您知道將創建的特定列,這也會導致錯誤:
x %>%
mutate(across(
.cols = contains('x'),
.fns = list(
new = ~(.x*2),
new2 = x_new
)
))
#> Error in `mutate()`:
#> ! Problem while computing `..1 = across(.cols = contains("x"), .fns =
#> list(new = ~(.x * 2), new2 = x_new))`.
#> Caused by error:
#> ! object 'x_new' not found
第二個問題是您需要確保它調用了適當的*_new
列。 這可以通過訪問cur_column()
來創建一個符號來完成,該符號在 data.frame 的上下文中進行評估。
x %>%
mutate(across(
.cols = contains('x'),
.fns = list(
new = ~(.x*2)
)
)) %>%
mutate(across(
.cols = matches("x[[:digit:]]?$"),
.fns = list(
new2 = ~eval(as.symbol(paste0(cur_column(), "_new"))) * 4
)
))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.