Заправка иглы: поиск имени фактического аргумента, соответствующего формальному из внешней функции - PullRequest
0 голосов
/ 01 мая 2019

Функция strip() ниже пытается создать краткий отчет о результате своей работы через тройник (%T>%). Поскольку эта функция, в свою очередь, передается функции-обертке, а затем purrr::pwalk, которая будет поочередно снабжать ее набором информационных кадров, я хочу получить отчет о ее работе на каждом информационном кадре вместе с именем информационного кадра; то есть имя фактического кадра данных, который предоставляется для соответствия формальному аргументу tib в функции ниже. В приведенном примере это будет "tst_df". Я не знаю имен до запуска функции, так как они составлены из имен файлов, прочитанных с диска и различных других входных данных.

Отчасти к моему удивлению, у меня практически все это работает, за исключением получения имени поставляемого кадра данных. В приведенном ниже примере код, который должен сделать это, - enexpr(XX), но я также попытался expr(XX), и оба эти выражения применяются к tib или точке (.), с или без предшествующий !!. Также deparse(substitute()) на XX, tib и ., но без взрыва.

Я вижу, что имена сначала разбираются по значениям, а затем снова, может быть, по каждой ступени канала, включая 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

1 Ответ

0 голосов
/ 01 мая 2019

Просто сохраните имя 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
...