簡體   English   中英

dplyr::mutate_if - 使用創建的變量來構建新的變量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM