代码之家  ›  专栏  ›  技术社区  ›  Tyler Law

tidyr:在函数中使用mutate

  •  5
  • Tyler Law  · 技术社区  · 6 年前

    我想使用tidyverse中的mutate函数在旧列的基础上创建一个新列,只使用数据帧和字符串(表示列标题)作为输入。

    我可以在不使用tidyverse的情况下使其工作(请参见下面的函数f),但我希望使用tidyverse使其工作(请参见下面的函数f.tidy)

    是否有人可以发布一个使用内部函数调用的mutate添加此列的解决方案?

    df <- data.frame('test' = 1:3, 'tcy' = 4:6)
    # test tcy
    #    1   4
    #    2   5
    #    3   6  
    
    f.tidy <- function(df, old.col, new.col) {
      df.rv <- df %>%
        mutate(new.col = .data$old.col + 1)
      return(df.rv)
    }
    
    f <- function(df, old.col, new.col) {
      df.rv <- df
      df.rv[, new.col] <- df.rv[, old.col] + 1
      return(df.rv)
    }
    
    old.col <- 'tcy'
    new.col <- 'dan'
    
    f.tidy(df = df, old.col = old.col, new.col = new.col)
    # Evaluation error: Column 'old.col': not found in data
    f(df = df, old.col = old.col, new.col = new.col)
    # Produces Desired Output:
    # test tcy dan
    #    1   4   5
    #    2   5   6
    #    3   6   7
    
    1 回复  |  直到 6 年前
        1
  •  6
  •   akrun    6 年前

    我们可以使用 rlang 将其转换为符号,然后使用 !!

    f.tidy <- function(df, old.col, new.col) {
    
      df %>%
          mutate(!! (new.col) := !!rlang::sym(old.col) + 1)
    
    }
    
    f.tidy(df = df, old.col = old.col, new.col = new.col)
    #   test tcy dan
    #1    1   4   5
    #2    2   5   6
    #3    3   6   7
    

    或者另一种选择是 mutate_at 具有 rename_at

    f.tidy <- function(df, old.col, new.col) {
    
     df %>%
        mutate_at(vars(old.col),  funs(new = .+ 1)) %>%
        rename_at(vars(matches("new")), ~ new.col)
    
     }
    
    f.tidy(df = df, old.col = old.col, new.col = new.col)
    #   test tcy dan
    #1    1   4   5
    #2    2   5   6
    #3    3   6   7