[R] How to avoid ifelse statement converting factor to character
Peter Dalgaard
p.dalgaard at biostat.ku.dk
Fri Jun 26 23:27:59 CEST 2009
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).
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).
....
>>> 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
> 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, but this is not implemented. I.e. you could
have had the effect of.
> x <- as.raw(x)
> x[1] <- r
> x
[1] 01
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
>>>
>>> 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
--
O__ ---- Peter Dalgaard Øster Farimagsgade 5, Entr.B
c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K
(*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
More information about the R-help
mailing list