Как проверить наличие определенных предупреждений, выдаваемых функцией «warnings ()»? - PullRequest
0 голосов
/ 30 апреля 2019

Проблема

Я использую функцию read_delim для чтения большого количества CSV-файлов (без запятых).Это вызывает предупреждения, потому что некоторые столбцы имеют одинаковое имя.Я не хочу редактировать исходные файлы, и я не могу изменить имена столбцов, пока я читаю их с помощью read_delim.Так что эти предупреждения неизбежны.Однако я хотел бы сделать тест, чтобы это были только генерируемые предупреждения, и что нет других предупреждений, таких как неправильные спецификации столбцов и т. Д.

Что я могу думать о себе

Я могу записать предупреждения с помощью myWarnings <- warnings() после запуска кода, но я не уверен, как что-либо проверить с этим.Проблема в том, что myWarnings - это список класса warnings, с которым я не знаю, как проверить.Например, myWarnings[[1]] производит NULL, поэтому я не могу проверить элемент на элемент.Это также не символьный вектор, а список.

Обычный способ сделать это - зафиксировать предупреждения во время работы функции.Например, testthat::expect_warning(read_delim(...)), но для этого мне нужно будет выполнить свой код дважды: один раз для результата и один раз для тестирования.Я не хочу этого делать, потому что это занимает слишком много времени (и это не очень чистый способ сделать что-то).

Код

# Pseudocode because you don't have my input files anyway
library(tidyverse)
myInputs <- list.files("myFolder", pattern = ".csv$")
myColTypes <- cols(col1 = col_character(), col2 = col_logical(), etc.)
myData <- map(myInputs, read_delim, delim = "|", col_types = myColTypes)

После этого R говорит мне в консоли: There were 36 warnings (use warnings() to see them).Каждое из этих предупреждений гласит: Duplicated column names deduplicated: 'col' => 'col_1' [32], 'col' => 'col_2' [54], 'col' => 'col_3' [211].

Я хотел бы иметь возможность сделать что-то вроде этого:

# Again pseudocode, because this is what I would like but it doesn't work.
myWarnings <- warnings()
testthat::expect_equal(
    myWarnings,
    warning("Duplicated column names deduplicated: 'col' => 'col_1' [32], 'col' => 'col_2' [54], 'col' => 'col_3' [211]"
)

1 Ответ

1 голос
/ 30 апреля 2019

Вы можете использовать testthat::expect_named().Зачем?Список, который вы получаете от warnings(), является именованным списком, где имена являются предупреждающими сообщениями.Давайте рассмотрим пример:

for ( i in 1:10 ) {
    x <- log(-i)
}
# Warning messages:
# 1: In log(-i) : NaNs produced
# ...
# 10: In log(-i) : NaNs produced
w <- warnings()
str(w)
# List of 10
#  $ NaNs produced: language log(-i)
#  ...
#  $ NaNs produced: language log(-i)
#  - attr(*, "dots")= list()
#  - attr(*, "class")= chr "warnings"
names(w)
# [1] "NaNs produced" "NaNs produced" "NaNs produced" "NaNs produced"
# [5] "NaNs produced" "NaNs produced" "NaNs produced" "NaNs produced"
# [9] "NaNs produced" "NaNs produced"

Затем мы можем использовать testthat::expect_named() для проверки равенства предупреждающих сообщений:

testthat::expect_named(w, rep("NaNs produced", 10))
...