rpl
rpl

Reputation: 451

R: ifelse, return a subset based on a condition

I am still learning R and bumped into something that is beyond my comprehansion. I spent like 2 hours trying to figure it out on my own and failed :-( .

I have a data.frame (let's think of iris, for instance) that I want to subset using ifelse. If the 1st row is a "setosa", I want a data.frame back with first 50 rows, if not, the next 100 rows. See below.

data (iris)
a <- ifelse(iris$Species[1] == "setosa", iris[1:50,],iris[51:150,])

I would expect the above to return a subset of the original data.frame, but what I actually get is

[[1]]
 [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 4.8 4.3 5.8 5.7 5.4 5.1 5.7 5.1 5.4 5.1 4.6
[24] 5.1 4.8 5.0 5.0 5.2 5.2 4.7 4.8 5.4 5.2 5.5 4.9 5.0 5.5 4.9 4.4 5.1 5.0 4.5 4.4 5.0 5.1 4.8
[47] 5.1 4.6 5.3 5.0

I simply don't get it...

Upvotes: 2

Views: 9650

Answers (3)

Tim
Tim

Reputation: 7474

You can read in ifelse docs that

ifelse returns a value with the same shape as test which is filled with elements selected from either yes or no depending on whether the element of test is TRUE or FALSE.

So if test is a vector, it returns a vector, if it is a single value it returns a single value etc. If you provide wrong arguments, it produces rubbish results. To give examples

> ifelse(1:10<5, 1, 0)
[1] 1 1 1 1 0 0 0 0 0 0
> ifelse(1:10<5, 0, 1:10)
[1]  0  0  0  0  5  6  7  8  9 10
> ifelse(TRUE, 1, 0)
[1] 1
> ifelse(TRUE, 1:10, 0)
[1] 1

In your case you should rather use

if (condition) ... else ...

The ifelse and if ... else ... are different functions, ifelse is not a one-liner for the other function. What ifelse does is it goes through some object and replaces values in this object based on some test returning TRUE or FALSE for each value to be replaced.

Upvotes: 5

Duf59
Duf59

Reputation: 532

Answer to the ifelse problem is given above. Then depending on your actual application, you could also subset in this way:

subset(iris, Species==Species[1])

Upvotes: 0

jogo
jogo

Reputation: 12569

if (iris$Species[1] == "setosa") a <- iris[1:50,] else a <- iris[51:150,]

or

a <- if (iris$Species[1] == "setosa") iris[1:50,] else iris[51:150,]

Upvotes: 0

Related Questions