[R] How to avoid ifelse statement converting factor to character
Craig P. Pyrame
crappyr at gmail.com
Sat Jun 27 01:03:13 CEST 2009
Dear Peter,
Thank you for the explanations. Some further questions are inlined below.
Best regards,
Craig
Peter Dalgaard wrote:
> Craig P. Pyrame wrote:
>> Stavros Macrakis wrote:
>>> It gives me a headache, too! I think you'll have to wait for a more
>>> expert user than me to supply explanations of these behaviors and
>>> their rationales.
>>
>> Thanks, Stavros. I hope someone with expertise will shed more light
>> on this, and in the meantime I'll try to learn more from the manuals.
>
> Well first, you (and others) should shake any bees relating to "raw"
> objects out of your bonnet. The raw type should be viewed as an add-on
> enabling access to low-level data structures, not as a fundamental
> data type in R. The original data modes are logical, numeric,
> character, with "upwards" coercion rules (and some further twiddles
> for storage modes of numerics).
I think I've seen examples in the list's archives where downwards
coercion rules were used, but I am not sure.
>
> One particular aspect is that in the original system, logical works as
> a "wild card" type that can be coerced to all the others (hence NA has
> mode "logical", which causes some confusion at first notice).
That's right, I find it confusing at first.
>
> ....
>>>> Why does this fail:
>>>> > r = as.raw(TRUE) > ifelse(TRUE, r, r) => error
>>>> This gives an error which I take for saying that raw cannot be coerced
>>>> to logical, but yes it can:
>>>> > as.logical(r) => TRUE
>
> Wrong. Or rather, irrelevant. The error is
> > ifelse(TRUE,r,r)
> Error in ans[test & !nas] <- rep(yes, length.out = length(ans))[test &
> : incompatible types (from raw to logical) in subassignment type fix
> Notice "subassignment type fix". This corresponds to this sort of
> operation
> > r <- as.raw(TRUE)
> > x <- TRUE
> > x[1] <- r
> Error in x[1] <- r : incompatible types (from raw to logical) in
> subassignment type fix
> Now, notice that when the coercion is "bigger to smaller" the fix is
> to coerce on the left side
What do you mean by "coercion from bigger to smaller"? What I thought
should happen in the example above is to have x coerced upwards to logical.
>
> > y <- rep(TRUE,5)
> > y[1] <- 5
> > y
> [1] 5 1 1 1 1
>
> So the thing that might be expected here would be that x be coerced to
> raw before the assignment,
No, I would expect upwards coercion, just as in the example immediately
above. I would expect r to be coerced to logical.
> but this is not implemented. I.e. you could have had the effect of.
> > x <- as.raw(x)
> > x[1] <- r
> > x
> [1] 01
No, I would rather expect to have the effect of:
> x[1] <- as.logical(r)
>
> This is designed not to happen automatically. I didn't write the code
> but I suppose one possible reason is that the raw mode does not allow
> missing values (or negative numbers for that matter, everything is
> 0-255).
> It also cuts the other way - no subassignment fixes are defined for
> "raw":
> > x <- as.raw(1:10)
> > x[3] <- NA
> Error in x[3] <- NA : incompatible types (from logical to raw) in
> subassignment type fix
> > x[3] <- TRUE
> Error in x[3] <- TRUE : incompatible types (from logical to raw) in
> subassignment type fix
> > x[3] <- 4
> Error in x[3] <- 4 : incompatible types (from double to raw) in
> subassignment type fix
> > x[3] <- 4L
> Error in x[3] <- 4L : incompatible types (from integer to raw) in
> subassignment type fix
>
I don't understand any of these. If you can do the following:
> as.raw(TRUE) => 1
> as.raw(4L) => 04
> as.raw(-1) => 00, with a warning
> as.raw(NA) => 00, with a warning
Why can't this be done automatically. What would be wrong in having this
done automatically, with a warning if needed?
>
>>>>
>>>> and raw can even be used as the condition vector in ifelse:
>>>> > ifelse(r, 1, 2) => 1
>
> Yes, but that's a different issue. Ifelse has the C language
> convention that anything nonzero is TRUE.
> > ifelse(pi,2,1)
> [1] 2
>
That's a news for me. The man page does not explain that! It says
"test: an object which can be coerced to logical mode" and also "Missing
values in test give missing values in the result". If ifelse were
working the C way, I would expect 1 as the result here:
> ifelse(as.raw(1), 1, 2) => error
> as.raw(1) == 0 => FALSE
The raw 1 is nonzero.
Best regards,
Craig
More information about the R-help
mailing list