Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R paste() now collapses as.hexmode() zeroes

Tags:

r

I'm generating hex colour codes. In R3.6.2

paste(as.hexmode(c(213,94,0)))

generates

 "d5" "5e" "00"

While in R4.4.1 it generates

 "d5" "5e" "0"

resulting in an invalid hexcode ("#d55e0") and broken code

paste() now seems not to recognise the 'hexmode' attribute - rather it treats the result of as.hexmode() as a simple integer. Is this change to be expected?

like image 640
user2078096 Avatar asked Dec 29 '25 14:12

user2078096


1 Answers

Yes this is expected. A change in R 4.2 was:

as.character(<obj>) for "hexmode" or "octmode" objects now fulfils the important basic rule as.character(x)[j] === as.character(x[j])

In R 3.6, as.character.hexmode(x) was a wrapper for format.hexmode(x):

x <- c(213, 94, 0)
as.character(as.hexmode(x[3])) # 0
as.character(as.hexmode(x))[3] # 00

However, in R ≥ 4.2, it is basically equivalent to sprintf("%x", as.integer(x)):

as.character(as.hexmode(x[3])) # 0
as.character(as.hexmode(x))[3] # 0

This apparently has surprising consequences for you and others relying on zero-padding. This message from Martin Maechler (R Core Team member) explains the rationale. In any case, to get the desired behaviour, you can use format.hexmode() directly:

format(as.hexmode(x), width = 2)
# [1] "d5" "5e" "00"

The behaviour of format.hexmode() is to automatically pad the width to the max digits of any value in the vector, which in this case is two, so width = 2 is not necessary here. However, it may be better to explicitly set with width argument cover all cases. For example, if you were generating the code for black, you would need to set width to get zero-padded output:

format(as.hexmode(c(0, 0, 0)))
# [1] "0" "0" "0"
format(as.hexmode(c(0, 0, 0)), width = 2)
# [1] "00" "00" "00"

Using format.hexmode() will replicate the R 3.6 paste() behaviour on both R ≥ 4.2 and <4.2.

like image 141
SamR Avatar answered Jan 01 '26 05:01

SamR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!