【问题标题】:How can I access a column name within a function in a mutate call?如何在 mutate 调用中访问函数中的列名?
【发布时间】:2019-10-24 20:48:11
【问题描述】:

我正在使用我编写的函数更改一列以在 R 中创建一个新列。

在我的函数中,我想发送一条消息,其中包含正在更改的列的名称。

如何在 mutate 调用中从函数内部访问正在变异的列名?

可重现的例子:

data <- tribble(
 ~colB, 
  1, 
  2, 
  3
)

# Function that will be used in the mutate
add1 <- function(numeric_vector) {
  return(1 +numeric_vector)

  # I want to message the user the name of the column they are mutating
  # This simply returns the entire vector
  message("You mutated", numeric vector)

  # This returns 'numeric_vector'
  message("You mutated", quo_name(quo(numeric_vector)))

}

# Desired Output:
data %>% 
  mutate(colC = add1(colB))

You mutated colB
 colB  colC
 <dbl> <dbl>
   1     2
   2     3
   3     4

【问题讨论】:

    标签: r tidyverse dplyr rlang


    【解决方案1】:

    使用返回name 类对象的substitute。我们已将message 调用包装在on.exit 中,以确保它在计算之后运行,以便在计算失败时不会运行它。如果这不重要,则将on.exit(message(...)) 替换为message(...)。注意add1 本身不使用任何包。

    library(dplyr)
    
    add1 <- function(numeric_vector) {
      on.exit(message("You mutated ", substitute(numeric_vector)))
      1 + numeric_vector
    }
    
    BOD %>% mutate(Time = add1(Time))
    

    给予:

    You mutated Time
      Time demand
    1    2    8.3
    2    3   10.3
    3    4   19.0
    4    5   16.0
    5    6   15.6
    6    8   19.8
    

    rlang

    要使用 rlang,请使用该软件包中的 enexpr。 dplyr 将使其可用。 enexpr 返回一个 name 类对象。

    enexprsubstitute 相似,但会影响处理的一个区别是substitute 将提取承诺的代码部分,无论承诺是否已被强制(即评估);但是,enexpr 将提取非强制承诺的代码,但会提取强制承诺的值。由于我们需要代码部分,我们必须确保enexpr(numeric_vector) 运行之前 numeric_vector 用于计算。为了确保我们引入了一个新变量 arg_name,它在开始时运行,确保 enexpr 具有非强制参数。

    library(dplyr)
    
    add2 <- function(numeric_vector) {
      arg_name <- enexpr(numeric_vector)
      on.exit(message("You mutated ", arg_name))
      1 + numeric_vector
    }
    
    BOD %>% mutate(Time = add2(Time))
    

    【讨论】:

      【解决方案2】:

      我想你想要

      add1 <- function(numeric_vector) {
        message(paste("You mutated", quo_name(enquo(numeric_vector))))
        return(1 + numeric_vector)
      }
      

      请注意,您必须在return() 之前打印您的消息。 return() 之后的任何内容都不会在函数中运行,因为您在点击该语句时退出。此外,您可以使用enquo() 获取变量以获取其名称。而且您需要在它仍处于承诺状态时获取它的名称,这意味着在您实际使用它的值之前。

      【讨论】:

        猜你喜欢
        • 2022-06-13
        • 2021-03-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-09
        • 2018-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多