Почему %in% сравнивает тип данных while, == может сравнивать строки?

#r #data.table

#r #data.table

Вопрос:

У меня довольно простой вопрос. Может ли кто-нибудь объяснить мне, почему первое работает, а второе — нет, и почему важен тип данных даты?

 library(data.table)

test.table <- data.table(Dates = 
                           as.Date(c("2020-08-31", "2020-01-31", "2020-08-31", "2010-01-01")))

test.table[Dates == "2020-08-31"]

test.table[Dates %in% c("2020-08-31")]
 

Комментарии:

1. Я думаю, что это не связано с data.table и что ответ можно найти в ?'==' и ?'%in%' в частях обсуждения принуждения.

2. %in% также может проявлять гибкость: TRUE %in% 1 дает TRUE

Ответ №1:

Это не относится к data.table. В документации help("%in%) говорится следующее:

Факторы, необработанные векторы и списки преобразуются в символьные векторы, а затем x и table приводятся к общему типу (более позднему из двух типов в порядке R, логический < целое число < числовой < сложный < символ) перед сопоставлением.

Общий тип переменной даты и символьной переменной — «character». Поскольку документация относится к типам, а не к классам, as.character.Date не используется. Я предполагаю, что внутренние двойники переменной даты принудительно обрабатываются и сравниваются.

Вы никогда не должны полагаться на автоматическое принудительное сравнение. Всегда используйте явное принуждение:

 Dates %in% as.Date("2020-08-31")

Dates == as.Date("2020-08-31")
 

Ответ №2:

Что касается

 test.table[Dates %in% c("2020-08-31")]
 

c("2020-08-31") обрабатывается как класс символов, в то время test.table$Dates как является классом даты. Следовательно, они не совпадают при использовании %in% .

Если вы преобразуете символ Dates как или c("2020-08-31") как дату, вы получите то же совпадение.

 test.table[as.character(Dates) %in% c("2020-08-31")]

test.table[Dates %in% as.Date("2020-08-31")]