`print` в` ifelse`

Мне интересно, почему ifelse(1<2,print("true"),print("false")) возвращает

[1] "true"
[1] "true"

тогда как ifelse(1<2,"true","false") возвращает

[1] "true"

Я не понимаю, почему print внутри ifelse возвращает "true" дважды

Ответ 1

Это происходит потому, что ifelse всегда будет возвращать значение. При запуске ifelse(1<2,print("true"),print("false")) выбирается условие yes. Это условие является вызовом функции для печати "true" на консоли, и так оно и есть.

Но функция print() также возвращает свой аргумент, но невидимо (например, присвоения), иначе вы бы дважды напечатали значение, напечатанное дважды. Когда выражение yes оценивается, его результатом является то, что возвращает ifelse, а ifelse не возвращается невидимо, поэтому он печатает результат, так как это выполнялось в глобальной среде и без какого-либо присвоения.

Мы можем проверить некоторые варианты и проверить, что происходит.

> result <- print("true")
[1] "true" # Prints because the print() function was called.
> result
[1] "true" # The print function return its argument, which was assigned to the variable.

> ifelse(1<2, {print("true");"TRUE"},print("false"))
[1] "true" #This was printed because print() was called
[1] "TRUE" #This was printed because it was the value returned from the yes argument

Если мы назначим это ifelse()

> result <- ifelse(1<2, {print("true");"TRUE"},print("false"))
[1] "true"
> result
[1] "TRUE"

Мы также можем посмотреть на случай, когда оцениваются оба условия условия:

> ifelse(c(1,3)<2, {print("true");"TRUE"},{print("false");"FALSE"})
[1] "true" # The yes argument prints this
[1] "false" # The no argument prints this
[1] "TRUE"  "FALSE" # This is the returned output from ifelse()

Вы должны использовать ifelse для создания нового объекта, а не для выполнения действий на основе условия. Для этого используйте if else. R Inferno имеет хороший раздел (3.2) о различии между ними.

Ответ 2

Просто добавьте некоторые аргументы в прекрасный ответ Молькса. Одна из причин, почему это происходит, зависит от этого:

length(print("true"))
[1] "true"
[1] 1
length(length(print("true")))
[1] "true"
[1] 1
length(length(length(print("true"))))
[1] "true"
[1] 1

... и так далее...

В руководстве R указано, что:

да вернуть значения для истинных элементов теста

обратите внимание на значения, а не значение, здесь мы имеем два значения: один - объект функции печати (который должен печатать "истина", скорее всего, это вызов функции, в данном случае print, в результате чего вектор символов с true), а другой - выходной вывод "true", который является правильным элементом оператора ifelse.

Его можно было бы избежать просто:

 ifelse(1 < 2, "true" , "false" )
[1] "true"

Ответ 3

Не печатает ли TRUE и возвращает TRUE одновременно?

Так, например, использование cat вместо печати изменит результат...

Это в основном связано с комментарием Ольфельдеров.