【问题标题】:dplyr mutate multiple columns based on names in vectorsdplyr 根据向量中的名称对多列进行变异
【发布时间】:2018-04-17 21:26:33
【问题描述】:

我想使用dplyr's mutate 函数将两列相乘。

但我不想为每个变异条件写一个新行,而是使用存储在向量var1var2 中的列的名称。例如,最后我想在现有的bankdata 中添加一个名为result1 的附加列,其中包含将列现金和贷款相乘的结果。这将一直持续到创建了 3 个新列为止。

可重现的代码:

bankname <- c("Bank A", "Bank B", "Bank C", "Bank D", "Bank E")
bankid <- c(1, 2, 3, 4, 5)
year <- c(1881, 1881, 1881, 1881, 1881)
totass <- c(244789, 195755, 107736, 170600, 32000000)
cash <- c(7250, 10243, 13357, 35000, 351266)
bond <- c(20218, 185151, 177612, 20000, 314012)
loans <- c(29513, 2800, NA, 5000, NA)
bankdata <- data.frame(bankname, bankid, year, totass, cash, bond, loans)

向量 var1var2 包含我要相乘的列名 (cash*loans, bond*cash, loans*bankid),output 是新列的名称:

var1 <- c("cash", "bond", "loans")
var2 <- c("loans","cash", "bankid")
output <- c("result1", "result2", "result3")

我想做类似的事情:

bankdata %>%
  mutate_at(.funs = funs(output = var1*var2), vars(var1, var2))

bankdata %>%
  mutate_at(.funs = funs(result1 = cash*., result2 = bond*., result3 = loans*.), vars(var2))

【问题讨论】:

    标签: r dplyr tidyeval


    【解决方案1】:

    使用tidyeval approach,我们构建了一个可以将字符串作为输入然后创建新列的函数。注意rlang::sym!! 的使用(砰砰)。

    之后,我们可以使用purrr::pmap_dfc 循环遍历var1var2 以创建名称由output 提供的新列

    library(tidyverse)
    
    bankname <- c("Bank A", "Bank B", "Bank C", "Bank D", "Bank E")
    bankid <- c(1, 2, 3, 4, 5)
    year <- c(1881, 1881, 1881, 1881, 1881)
    totass <- c(244789, 195755, 107736, 170600, 32000000)
    cash <- c(7250, 10243, 13357, 35000, 351266)
    bond <- c(20218, 185151, 177612, 20000, 314012)
    loans <- c(29513, 2800, NA, 5000, NA)
    bankdata <- data.frame(bankname, bankid, year, totass, cash, bond, loans)
    
    originalNames <- names(bankdata)
    var1   <- c("cash", "bond", "loans")
    var2   <- c("loans","cash", "bankid")
    output <- c("result1", "result2", "result3")
    
    my_mutate <- function(df, var1, var2, output) {      
      var1   <- rlang::sym(var1)
      var2   <- rlang::sym(var2)
      output <- rlang::sym(output)
    
      df <- df %>% 
        mutate(!! output := !! var1 * !! var2)
    
      return(df)
    }
    
    # test
    my_mutate(bankdata, var1[1], var2[1], output[1])
    
    #>   bankname bankid year   totass   cash   bond loans   result1
    #> 1   Bank A      1 1881   244789   7250  20218 29513 213969250
    #> 2   Bank B      2 1881   195755  10243 185151  2800  28680400
    #> 3   Bank C      3 1881   107736  13357 177612    NA        NA
    #> 4   Bank D      4 1881   170600  35000  20000  5000 175000000
    #> 5   Bank E      5 1881 32000000 351266 314012    NA        NA
    
    # loop through 3 lists simultaneously 
    # keep only original and result* columns
    pmap_dfc(list(var1, var2, output), ~ my_mutate(bankdata, ..1, ..2, ..3)) %>% 
      select(!! originalNames, starts_with("result"))
    
    #>   bankname bankid year   totass   cash   bond loans   result1      result2
    #> 1   Bank A      1 1881   244789   7250  20218 29513 213969250    146580500
    #> 2   Bank B      2 1881   195755  10243 185151  2800  28680400   1896501693
    #> 3   Bank C      3 1881   107736  13357 177612    NA        NA   2372363484
    #> 4   Bank D      4 1881   170600  35000  20000  5000 175000000    700000000
    #> 5   Bank E      5 1881 32000000 351266 314012    NA        NA 110301739192
    #>   result3
    #> 1   29513
    #> 2    5600
    #> 3      NA
    #> 4   20000
    #> 5      NA
    

    reprex package (v0.2.0) 于 2018 年 4 月 18 日创建。

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      • 2016-04-30
      • 1970-01-01
      相关资源
      最近更新 更多