穿针:找到对应于外部函数形式的实际参数的名称

问题描述 投票:0回答:1

下面的函数strip()试图通过三通管(%T>%)生成一个关于其操作结果的简要报告。因为这个函数反过来被交给一个包装器函数,然后交给purrr::pwalk,它将逐个为它提供一堆数据帧,我想得到一个关于每个数据帧的操作的报告以及数据帧名称;也就是说,提供的实际数据帧的名称对应于下面函数中的形式参数tib。在提供的示例中,这将是"tst_df"。我不知道运行该函数之前的名称,因为它们是从从磁盘读取的文件名和各种其他输入构造的。

令我惊讶的是,除了获取提供的数据帧的名称之外,我实际上几乎所有这些工作都有效。在下面的例子中,应该执行此操作的代码是enexpr(XX),但我也尝试过expr(XX),这两个表达式都应用于tib或点(.),有或没有前面的!!。还有deparse(substitute())XXtib.,但没有爆炸刘海。

我看到名称最初是通过值传递去掉的,然后可能是管道的每个阶段,包括T,再次,也许是,XX = .之后的匿名函数中的(T)。但我知道R + tidyverse会有办法。我只是希望它不涉及提供一个整数来向后计数调用堆栈

tst_df <- tibble(A = 1:10, B = 11:20, C=21:30, D = 31:40)
tst_df    
################################################################################
# The strip function expects a non-anonymous dataframe, from which it removes
# the rows specified in remove_rows and the columns specified in remove_cols. It
# also prints a brief report; just the df name, length and width.
strip <- function(tib, remove_rows = FALSE, remove_cols = NULL){
  remove_rows <- enquo(remove_rows)
  remove_cols <- enquo(remove_cols)
  out <- tib %>%
    filter(! (!! remove_rows))  %>%
    select(- !! remove_cols) %T>% (function(XX = .){
      function(XX = .)print(
          paste0("length of ", enxpr(XX), " = ", nrow(XX), " Width = ", ncol(XX)))
          cat("\n")
        })
  out  
}

out_tb <- strip(tib = tst_df, remove_rows = (A < 3 | D > 38),  remove_cols = c(C, D))
out_tb
r metaprogramming pipeline tidyverse variable-names
1个回答
0
投票

只需在您的函数开头保存tib的名称,它将由您的记者功能找到:

strip <- function(tib, remove_rows = FALSE, remove_cols = NULL) {
  remove_rows <- enquo(remove_rows)
  remove_cols <- enquo(remove_cols)
  tib_name <- as.character(substitute(tib))
  report <- function(out) {
    cat("output length of", tib_name, "=", nrow(out), ", width =", ncol(out), "\n")
  }

  tib %>%
    filter(! (!! remove_rows))  %>%
    select(- !! remove_cols) %T>%
    report
}

out_tb <- strip(tib = tst_df, remove_rows = (A < 3 | D > 38),  remove_cols = c(C, D))
output length of tst_df = 6 , width = 2
© www.soinside.com 2019 - 2024. All rights reserved.