I'm running an experiment where I need to compare the consistency of RGB values selected from two different time points. To do this, I need to convert RGB to XYZ values which I know I can do using ConvertColor.
However! I can't figure out an efficient way of being able to convert multiple RGB values stored in data.table into XYZ using ConvertColor. I have a feeling the problem lies in the fact that I can't figure out how to store RGB values as numeric values rather than characters.
My data.table named syn_RGB will be set out as follows:
ID | Grapheme | RGB_1 | RGB_2 |
---|---|---|---|
S01 | A | (37, 13, 219) | (39, 23, 211) |
S01 | B | (50, 3, 19) | (40, 23, 11) |
S02 | A | (43, 57, 89) | (50, 50, 78) |
S02 | B | (48, 59, 199) | (50, 63, 178) |
S03 | A | (100, 123, 209) | (89, 112, 200) |
S03 | B | (89, 120, 199) | (87, 119, 175) |
RGB_1
is the RGB given for the first time, RGB_2
the RGB given the second time.
This is what I've tried so far:
syn_XYZ <- synRGB(,. (s_xyz = convertColor(RGB_1, from = "sRGB", to = "XYZ", clip = TRUE)), by =. (ID, Grapheme)]
Here I'm trying to convert all the RGB values listed in RGB_1
into XYZ
values for each participant and each grapheme and store them in syn_XYZ
.
I've tried converting the RGB values from characters to numeric using as.numeric
and strtoi
but it doesn't work as you can imagine.
I'm still relatively new to programming so if there's a far more efficient way than trying to do it like this, I would be very appreciative since this is the only way I can think of how to do it.
Thanks
I don't think
data.table
has anything "efficient" for this, it's just a handling of a string vector. As clunky as it looks, this works:Walk through, mostly inside-out:
regmatches(., gregexpr("\\d+", .))
extracts things that look like numbers into individual numbers; i.e.,"(37, 13, 219)"
is converted intoc("37", "13", "219")
; this returns alist
with the same length asnrow(syn_RGB)
lapply(., as.integer)
converts the list of strings into a list of integer; e.g.,list(c("37", "13", "219"), c("52", "3", "19"), ...)
intolist(c(37, 13, 219), c(52, 3, 19), ...)
.do.call(rbind, .)
converts that list of vectors into a matrix, and thenasplit(., 2)
converts it to a list of columns as we need.do.call(rgb, .)
calls thergb
function (once) with each of the three values of theasplit(., 2)
list as its arguments, adding the argument oflist(maxColorValue=255)
(sincergb
normally wants its values to be on[0,1]
).