R: sprintf список переменных смешанного типа

Я пытаюсь сгенерировать SQL-запрос с несколькими встроенными переменными с помощью sprintf.

Я храню SQL (он большой) с параметрами как %s как отдельный файл, а затем прочитайте его изнутри. Чтобы улучшить читабельность, я создал помощника:

fillSQLQuery <- function(query, params){
  #' fill query with params
  do.call(sprintf, as.list(c(query, params)))
}

Мои параметры - даты, факторы и строки. Когда я передаю их непосредственно в функцию, мои даты заменяются на целое число, а мой фактор - на его индекс (?). С другой стороны, когда я преобразую весь вектор с as.character, он пытается обработать все элементы в строку как даты, и возвращает NA или неправильные результаты для всех не-строк).

do.call(sprintf, 
        as.list(c(query,    
        c(as.character(startDateSequence[1]),  # POSix DATE  
          as.character(endDateSequence[1]),    # POSix DATE    
          lotTypes[1], id_list[1] ))))         # string, factor

Единственный способ решить проблему, которую я нашел, - это предварительно вручную преобразовать даты и типы в символы. Тем не менее, мне интересно, есть ли какой-нибудь "понятный" способ сделать это, такой простой и надежный, как питоны:

'query {p1}, {p2}'.format(p1=X, p2=Y)

1 ответ

Хорошо, вы не предоставили воспроизводимый пример, но ваше намерение ясно, поэтому вот код, который вы должны были предоставить, чтобы сделать этот хороший пример (самодостаточным и воспроизводимым):

x1 = Sys.Date() # Date
x2 = Sys.time() # POSIX datetime
x3 = "hello"    # character
x4 = factor("world", levels = c("world", "something"))  # factor

qry = "Select %s, %s, %s, %s from blah"

Теперь, когда настройка установлена, мы можем работать над решением. list это естественная структура для хранения предметов разных классов:

params = list(x1, x2, x3, x4)

И мы можем изменить вашу функцию, чтобы преобразовать каждый элемент списка в character Перед использованием sprintf:

fillSQLQuery = function(query, params){
  params = lapply(params, as.character)
  do.call(sprintf, c(query, params))
}

fillSQLQuery(qry, params)
# [1] "Select 2016-11-05, 2016-11-05 17:19:29, hello, world from blah"
Другие вопросы по тегам