[R] How to avoid ifelse statement converting factor to character

Patrick Burns pburns at pburns.seanet.com
Thu Jun 25 10:02:51 CEST 2009


This sort of experience is why 'The R Inferno'
came into existence.


Patrick Burns
patrick at burns-stat.com
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of "The R Inferno" and "A Guide for the Unwilling S User")

Craig P. Pyrame wrote:
> 
> Dear Stavros,
> 
> What you discuss below is somewhat scary to me as an R newbie.  Is this 
> just an incident, a bug perhaps, or rather the way things typically go 
> in R, as your "Welcome to R!" seems to suggest?  I have just started to 
> learn R, and my initial euphoria of the "I can do anything with it!" 
> sort is gradually turning into an "I can't get why it doesn't work" and 
> "I can't get how to make this work" depression.  I would be happy to 
> blame this on my incompetence and incapability, but would also like to 
> hear if it is not R itself that causes me to fail.
> 
> Best regards,
> Craig
> 
> 
> Stavros Macrakis wrote:
>> On Wed, Jun 24, 2009 at 12:34 PM, Mark Na<mtb954 at gmail.com> wrote:
>>  
>>> The problem is that after running the ifelse statement, 
>>> data$SOCIAL_STATUS
>>> is converted from a factor to a character.
>>> Is there some way I can avoid this conversion?
>>>     
>>
>> I'm afraid that ifelse has very bizarre semantics when the yes and no
>> arguments don't have the same, atomic vector, type.
>>
>> The quick workaround for the bizarre semantics (though it can have a
>> significant efficiency cost) is this:
>>
>>        unlist( ifelse ( condition, as.list( yes ), as.list( no ) ) )
>>
>> (This isn't perfect, either, but...)
>>
>> Take a look at the man page for details and the warning:
>>
>>      The mode of the result may depend on the value of 'test', and the
>>      class attribute of the result is taken from 'test' and may be
>>      inappropriate for the values selected from 'yes' and 'no'.
>>
>> Some consequences of the definition of ifelse are:
>>
>> Even if the classes of the yes and no arguments are identical, the
>> result does not necessarily have that class:
>>
>>     ifelse(TRUE,as.raw(4),as.raw(5)) => error
>>
>>     ifelse(TRUE,factor('x'),factor('x')) => 1      (integer)
>>
>>     dates <- as.POSIXct(c('1990-1-1','2000-1-1'))
>>     ifelse(c(TRUE,FALSE),dates,dates)  =>  631170000 946702800  (double)
>>
>>     ifelse(c(TRUE,FALSE),factor(c('x','y')),factor(c('y','x'))) => 1 1
>>
>> If they have different classes, things get stranger:
>>
>>     ifelse(c(TRUE,FALSE),c("a","b"),factor(c("c","d")))  =>  "a" "2"
>>
>>     ifelse(c(TRUE,FALSE),list(1,2),as.raw(4))
>>     [[1]]
>>     [1] 1
>>
>>     [[2]]
>>     [1] 04
>>
>> Result is order-dependent:
>>
>>     ifelse(c(TRUE,FALSE),as.raw(4),list(1,2))
>>     Error in ans[test & !nas] <- rep(yes, length.out = 
>> length(ans))[test &  :
>>     incompatible types (from raw to logical) in subassignment type fix
>>
>> Welcome to R!
>>
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide 
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>




More information about the R-help mailing list