Почему ifelse преобразует data.frame в список: ifelse (TRUE, data.frame(1), 0))!= Data.frame(1)?

Я хочу вернуть data.frame из функции if TRUE, else вернуть NA с помощью return(ifelse(condition, mydf, NA))

Однако ifelse разбивает имена столбцов на data.frame.

Почему эти результаты отличаются?

> data.frame(1)
  X1
1  1
> ifelse(TRUE, data.frame(1), NA)
[[1]]
[1] 1

Дополнительная информация о dput():

> dput(ifelse(TRUE, data.frame(1), 0))
list(1)
> dput(data.frame(1))
structure(list(X1 = 1), .Names = "X1", row.names = c(NA, -1L), 
          class = "data.frame")

Ответ 1

ifelse обычно предназначен для векторизованных сравнений и имеет побочные эффекты, такие как: как он говорит в ?ifelse,

‘ifelse’ returns a value with the same shape as ‘test’ ...

поэтому в этом случае (test - вектор длины 1) он пытается преобразовать фрейм данных в "вектор" (список в этом случае) длины 1...

return(if (condition) mydf else NA)

В качестве общей точки проектирования я пытаюсь вернуть объекты той же структуры независимо от того, что бы я мог предпочесть

if (!condition) mydf[] <- NA
return(mydf)

Как правило, я считаю, что пользователи R (особенно из других языков программирования) начинают с использования if исключительно, найдите время, чтобы обнаружить ifelse, а затем чрезмерно использовать его, обнаружив позже, что вы действительно хотите использовать if в логических контекстах. Аналогичное происходит с & и &&.

См. также: