Helmut
★★★

Vienna, Austria,
2015-10-27 21:06
(1744 d 22:43 ago)

Posting: # 15584
Views: 6,909

## R inferno (rant) [Software]

Hi useRs!

Sometimes this nice piece drives me nuts.

x1 <- 12 x2 <- 13 x1 < x2 [1] TRUE     Bravo! Bravissimo!

ifelse (x1 < x2,   cat(x1, "less than", x2, "\n"),   cat(x1, "at least", x2, "\n")) 12 less than 13 Error in ifelse(x1 < x2, cat(x1, "less than", x2, "\n"), cat(x1, "at least",  :   replacement has length zero In addition: Warning message: In rep(yes, length.out = length(ans)) :   'x' is NULL so the result will be NULL
What the f…k?

if (x1 < x2) {   cat(x1, "less than", x2, "\n") } else {   cat(x1, "at least", x2, "\n") } 12 less than 13   Thank you sooo much!

Dif-tor heh smusma 🖖
Helmut Schütz

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes
ElMaestro
★★★

Belgium?,
2015-10-28 08:44
(1744 d 11:06 ago)

@ Helmut
Posting: # 15585
Views: 5,560

## R inferno (rant)

Haha Hötzi,

» ifelse (x1 < x2, »   cat(x1, "less than", x2, "\n"), »   cat(x1, "at least", x2, "\n"))» » 12 less than 13 » Error in ifelse(x1 < x2, cat(x1, "less than", x2, "\n"), cat(x1, "at least",  : »   replacement has length zero» In addition: Warning message:» In rep(yes, length.out = length(ans)) : »   'x' is NULL so the result will be NULL
»    What the f…k?

I agree ifelse(a,b,c) is a borderline silly function. It is in no way clear from the error message but b and c should be lean and mean variables rather than expressions. Therefore ifelse (a, do.this(blah), do.that(blah)) will only cause headache, at least as long as do.this/that(blah) doesn't return a value.
Like you I'd much prefer the classical if else construct.

I think this also goes to show that error messages should be user-friendly. If I am not mistaking only the guy who wrote the function understands that mumbo-jumbo. Preventive keelhauling would indeed seem to be a proper action to take.

I could be wrong, but...

Best regards,
ElMaestro

"Pass or fail" (D. Potvin et al., 2008)
d_labes
★★★

Berlin, Germany,
2015-10-28 09:42
(1744 d 10:07 ago)

@ ElMaestro
Posting: # 15587
Views: 5,520

## Vectorized if

Hi Öberster Größter Meister!

» I agree ifelse(a,b,c) is a borderline silly function.

Disagree. Very handy function if vectorized if is needed. Used it myself heavily in my codes for simulations.

» Like you I'd much prefer the classical if else construct.

Typical for coders coming from C, Fortran or so relying mostly on for loops and without vector constructs .
Will not work in R if you have vectors to compare. See "R Inferno" Circle 3.2, link in my post to Helmut.

» I think this also goes to show that error messages should be user-friendly.

Full ACK. Here R is as obscure or even more obscure as other languages. See here.

Regards,

Detlew
d_labes
★★★

Berlin, Germany,
2015-10-28 09:18
(1744 d 10:32 ago)

@ Helmut
Posting: # 15586
Views: 5,506

## R inferno (without rant)

Dear Helmut,

» ifelse (x1 < x2, »   cat(x1, "less than", x2, "\n"), »   cat(x1, "at least", x2, "\n"))» » 12 less than 13 » Error in ifelse(x1 < x2, cat(x1, "less than", x2, "\n"), cat(x1, "at least",  : »   replacement has length zero» In addition: Warning message:» In rep(yes, length.out = length(ans)) : »   'x' is NULL so the result will be NULL
»    What the f…k?

Not only SAS is a beast .

ifelse() is a (vectorized) function for conditional replacement / selection of values, not for conditional doing sumfink like output with cat().

From the man page of ifelse():
Usage
ifelse(test, yes, no)

Arguments
test  an object which can be coerced to logical mode.
yes   return values for true elements of test.
no    return values for false elements of test.

What is the return value of cat()?:
x <- cat("sumfink\n") x

Gives NULL.

From the man page of cat():
Value
None (invisible NULL).

All the f#+~ing behaviour as described and documented. No reason to rant .
For some inferno <- TRUE see Patrick Burns "R Inferno" Circle 3.2 and 8.2.7

If you really need a vectorized solution (if x1, x2 are vectors) I suggest the following:
cat(ifelse(x1 < x2,            paste0(x1, " less than ", x2),            paste0(x1, " at least ", x2 )           ), sep="\n")

Try it with
x1 <- c(12, 13) x2 <- c(13, 12)

BTW: Works of course also if x1 and x2 are scalars as in your example .

Regards,

Detlew