穿针引线:找到与外部函数形式对应的实参名称
Threading the needle: finding the name of the actual argument corresponding to a formal of an outer function
下面的函数 strip()
试图通过三通管 (%T>%
) 生成有关其操作结果的简短报告。因为这个函数依次被传递给包装函数,然后传递给 purrr::pwalk
,它将一个接一个地提供一堆数据帧,我想得到它对每个数据帧的操作报告以及数据帧姓名;也就是说,提供的实际数据帧的名称与下面函数中的正式参数 tib
相对应。在提供的示例中,这将是 "tst_df"
。我不知道函数 运行 之前的名称,因为它们是根据从磁盘读取的文件名和各种其他输入构造的。
令我有些惊讶的是,除了获取提供的数据框的名称外,我实际上几乎完成了所有这些工作。在下面的示例中,应该执行此操作的代码是 enexpr(XX)
,但我也尝试了 expr(XX)
,并且这两个表达式都应用于 tib
或点 (.
), 有或没有前面的 !!
。在 XX
、tib
和 .
上也有 deparse(substitute())
,但没有刘海。
我看到名称最初是通过按值传递剥离的,然后又一次,也许,通过管道的每个阶段,包括 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
只需在函数开头保存 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
下面的函数 strip()
试图通过三通管 (%T>%
) 生成有关其操作结果的简短报告。因为这个函数依次被传递给包装函数,然后传递给 purrr::pwalk
,它将一个接一个地提供一堆数据帧,我想得到它对每个数据帧的操作报告以及数据帧姓名;也就是说,提供的实际数据帧的名称与下面函数中的正式参数 tib
相对应。在提供的示例中,这将是 "tst_df"
。我不知道函数 运行 之前的名称,因为它们是根据从磁盘读取的文件名和各种其他输入构造的。
令我有些惊讶的是,除了获取提供的数据框的名称外,我实际上几乎完成了所有这些工作。在下面的示例中,应该执行此操作的代码是 enexpr(XX)
,但我也尝试了 expr(XX)
,并且这两个表达式都应用于 tib
或点 (.
), 有或没有前面的 !!
。在 XX
、tib
和 .
上也有 deparse(substitute())
,但没有刘海。
我看到名称最初是通过按值传递剥离的,然后又一次,也许,通过管道的每个阶段,包括 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
只需在函数开头保存 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