2013-09-23 4 views
6

В консоли, идти вперед и попробоватьПочему 1..99,999 == "1" .. "99,999" в R, но 100 000! = "100 000"?

> sum(sapply(1:99999, function(x) { x != as.character(x) })) 
0 

Для всех значений 1 через 99999, "1" == 1, "2" == 2 ..., 99999 == "99999" являются TRUE. Однако

> 100000 == "100000" 
FALSE 

Почему R имеет это странное поведение, и это ошибка? Каким будет обходной путь, например, проверить, действительно ли каждый элемент в символе атомного символа является числовым? Прямо сейчас я пытался проверить, x == as.numeric(x) для каждого x, но это не удается на некоторых наборах данных из-за вышеуказанной проблемы!

+1

Нет, эта сумма равна нулю, а не «TRUE» ... – Frank

+0

@JoshuaUlrich вы можете объяснить, как те, дубликаты? –

+0

Для проблемы, описанной в последнем абзаце, вы можете «совместить» свой векторный вектор-символ с «1: 100000» (который является целым вектором): 'match (as.character (1: 100000), 1: 100000)' , – Frank

ответ

12

Посмотрите на as.character(100000). Его значение не равно "100000" (обратите внимание на себя), и R по сути просто говорит вам об этом.

as.character(100000) 
# [1] "1e+05" 

Здесь из ?Comparison, правил АиРа для применения реляционных операторов значений различных типов:

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

Эти правила означают, что, когда вы проверяете ли, скажем, R сначала преобразует 1=="1" числовое значение на LHS в строку символов, а затем тесты для равенства строк символов на левой и правой частях. В некоторых случаях они будут равны, но в других случаях они не будут. В каких случаях производят неравенство будет зависеть от текущих настроек options("scipen") и options("digits")

Итак, когда вы набираете 100000=="100000", это , как если бы вы были на самом деле выполняет следующий тест. (Обратите внимание, что внутри, R может хорошо /, вероятно, использовать что-то другое, чем as.character() выполнить преобразование):

as.character(100000)=="100000" 
# [1] FALSE 
+0

Из '? '=='': «Если два аргумента являются атомарными векторами разных типов, один принуждается к типу другого, (убывающий) порядок приоритета является символом, сложным, числовым, целым, логическим и необработанным». Так правильно ли говорить, что сторона LHS становится коэрцитированной, а не наоборот? –

+2

@ SeñorO В 'x == y', если' y' является символом, тогда 'x' преобразуется, поэтому он *, как будто *' as.character (100000) == "100000" 'вызывается. Неважно, какая сторона бинарного оператора это; до тех пор, пока одна из пары будет символом, другая будет принуждена к символу, если это уже не так. –

+0

@ GavinSimpson - Спасибо за разъяснения. Я отредактировал один из них (бит о «* как будто *») в свой ответ. –

Смежные вопросы