R: Тестирование и подстановка элементов предложений - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь написать функцию для передачи некоторых аргументов quosure во внутреннюю область dplyr::select.Однако я хочу иметь возможность применять некоторые условия к аргументам после их предоставления.В этом конкретном случае, поскольку выбор столбцов, которые не существуют, приводит к ошибке, я хочу, чтобы функция проверяла, существуют ли столбцы, предоставленные вызывающей стороной, в кадре данных, переданном через аргумент tib, и удаляю те, которые не существуют, прежде чем я передамоператор quosure и unquoting для select.

Проблема в том, что, как только что-то находится внутри выражения, я больше не знаю, как им манипулировать.Я мог бы преобразовать имена в строки, исключить лишние имена, а затем преобразовать вектор строк обратно в символы с syms, что, я думаю, сработало бы в этом случае, потому что я отдельно передаю внутреннюю select структуру данных, в которойЯ хочу, чтобы они были оценены, но это сводит на нет все преимущества использования quosure, а затем искусственно поставляет их снова, что кажется окольным и не элегантным.Я бы хотел избежать хитрого решения, которое работает в этом конкретном случае, но не предлагает никаких полезных принципов в следующий раз.

library(tidyverse)

tst_tb <- tibble(A = 1:10, B = 11:20, C=21:30, D = 31:40)

################################################################################
# strip() expects a non-anonymous dataframe, from which it removes the rows
# specified (as a logical vector) in remove_rows and the columns specified (as
# unquoted names) in remove_cols. It also prints a brief report; just the df
# name, length and width, and the remaining column names.
strip <- function(tib, remove_rows = FALSE, remove_cols = NULL){
  remove_rows <- enquo(remove_rows)
  remove_cols <- enquo(remove_cols)
  tib_name    <- deparse(substitute(tib))  
  out <- tib %>%
    filter(! (!! remove_rows))  %>%
    select(- !! remove_cols) %T>% (function(XX = .){
      print(paste0(tib_name,": Length = ", nrow(XX), "; Width = ", ncol(XX)))
      cat("\n")
      cat("     Names: ", names(XX))
    })
  out  
}

Следующая строка не будет работать из-за E в remove_cols аргумент.Вы должны думать о E не как об одном имени из четырех или пяти, а как о 10 или 20 аргументах из нескольких сотен.

out_tb <- strip(tib = tst_df, remove_rows = (A < 3 | D > 36),  remove_cols = c(C, D, E))

out_tb

Желаемый результат:

# A tibble: 4 x 2
      A     B
  <int> <int>
1     3    13
2     4    14
3     5    15
4     6    16
...