Getting numerator and denominator of a fraction in R - r

Using the function fractions in the library MASS, I can convert a decimal to a fraction:
> fractions(.375)
[1] 3/8
But then how to I extract the numerator and denominator? The help for fractions mentions an attribute "fracs", but I can't seem to access it.

A character representation of the fraction is stored in an attribute:
x <- fractions(0.175)
> strsplit(attr(x,"fracs"),"/")
[[1]]
[1] "7" "40"

You can get the fracs attribute from your fraction object the following way, but it is just the character representation of your fraction :
x <- fractions(.375)
attr(x, "fracs")
# [1] "3/8"
If you want to access numerator and denominator values, you can just split the string with the following function :
getfracs <- function(frac) {
tmp <- strsplit(attr(frac,"fracs"), "/")[[1]]
list(numerator=as.numeric(tmp[1]),denominator=as.numeric(tmp[2]))
}
Which you can use this way :
fracs <- getfracs(x)
fracs$numerator
# [1] 3
fracs$denominator
# [1] 8

Related

How to convert a string to a formula with the type of `language` in R?

I want to convert a string with a formula to an object with the type language in order to use it as a formula.
How can I accomplish this?
A short example, that shows the problem:
formula <- "(1 - sin(x^3)"
> typeof(formula)
[1] "character"
A working reference is
> typeof(quote(1 - sin(x^3)))
[1] "language"
Of course, I can't just write formula in quote:
> quote(formula)
formula
So, is there a way to convert a string in a vector to something that as the typeof language?
Use parse:
y <- "1 - sin(x^3)"
p <- parse(text = y)[[1]]
p
## 1 - sin(x^3)
is.language(p)
## [1] TRUE
typeof(p)
## [1] "language"
x <- pi/4
eval(p)
## [1] 0.5342579
Note that is.language(parse(text = y)) is also TRUE but it is of type expression. On the other hand, eval(parse(text = y)) gives the same result.

How to convert a hex string to text in R?

Is there a function which converts a hex string to text in R?
For example:
I've the hex string 1271763355662E324375203137 which should be converted to qv3Uf.2Cu 17.
Does someone know a good solution in R?
Here's one way:
s <- '1271763355662E324375203137'
h <- sapply(seq(1, nchar(s), by=2), function(x) substr(s, x, x+1))
rawToChar(as.raw(strtoi(h, 16L)))
## [1] "\022qv3Uf.2Cu 17"
And if you want, you can sub out non-printable characters as follows:
gsub('[^[:print:]]+', '', rawToChar(as.raw(strtoi(h, 16L))))
## [1] "qv3Uf.2Cu 17"
Just to add to #jbaums answer or to simplify it
library(wkb)
hex_string <- '231458716E234987'
hex_raw <- wkb::hex2raw(hex_string)
text <- rawToChar(as.raw(strtoi(hex_raw, 16L)))
An alternative way that separates the two parts involved:
Turn the initial string into a vector of bytes (with values as hexadecimals)
Convert those raw bytes into characters (excluding any not printable)
Part 1:
s <- '1271763355662E324375203137'
sc <- unlist(strsplit(s, ""))
i1 <- (1:nchar(s)) %% 2 == 1
# vector of bytes (as character)
s_pairs1 <- paste0(sc[i1], sc[!i1])
# make explicit it is a series of hexadecimals bytes
s_pairs2 <- paste0("0x", s_pairs1)
head(s_pairs2)
#> [1] "0x12" "0x71" "0x76" "0x33" "0x55" "0x66"
Part 2:
s_raw1 <- as.raw(s_pairs2)
# filter non printable values (ascii < 32 = 0x20)
s_raw2 <- s_raw1[s_raw1 >= as.raw("0x20")]
rawToChar(s_raw2)
#> [1] "qv3Uf.2Cu 17"
We could also use as.hexmode() function to turn s_pairs1 into a vector of hexadecimals
s_pairs2 <- as.hexmode(s_pairs1)
head(s_pairs2)
#> [1] "12" "71" "76" "33" "55" "66"
Created on 2023-01-03 by the reprex package (v2.0.1)

Convert hex to decimal in R

I found out that there is function called .hex.to.dec in the fBasics package.
When I do .hex.to.dec(a), it works.
I have a data frame with a column samp_column consisting of such values:
a373, 115c6, a373, 115c6, 176b3
When I do .hex.to.dec(samp_column), I get this error:
"Error in nchar(b) : 'nchar()' requires a character vector"
When I do .hex.to.dec(as.character(samp_column)), I get this error:
"Error in rep(base.out, 1 + ceiling(log(max(number), base =
base.out))) : invalid 'times' argument"
What would be the best way of doing this?
Use base::strtoi to convert hexadecimal character vectors to integer:
strtoi(c("0xff", "077", "123"))
#[1] 255 63 123
There is a simple and generic way to convert hex <-> other formats using "C/C++ way":
V <- c(0xa373, 0x115c6, 0xa373, 0x115c6, 0x176b3)
sprintf("%d", V)
#[1] "41843" "71110" "41843" "71110" "95923"
sprintf("%.2f", V)
#[1] "41843.00" "71110.00" "41843.00" "71110.00" "95923.00"
sprintf("%x", V)
#[1] "a373" "115c6" "a373" "115c6" "176b3"
As mentioned in #user4221472's answer, strtoi() overflows with integers larger than 2^31.
The simplest way around that is to use as.numeric().
V <- c(0xa373, 0x115c6, 0x176b3, 0x25cf40000)
as.numeric(V)
#[1] 41843 71110 95923 10149429248
As #MS Berends noted in the comments, "[a]lso notice that just printing V in the console will already print in decimal."
strtoi() has a limitation of 31 bits. Hex numbers with the high order bit set return NA:
> strtoi('0x7f8cff8b')
[1] 2139946891
> strtoi('0x8f8cff8b')
[1] NA
To get a signed value with 16 bits:
temp <- strtoi(value, base=16L)
if (temp>32767){ temp <- -(65535 - temp) }
In a general form:
max_unsigned <- 65535 #0xFFFF
max_signed <- 32767 #0x7FFF
temp <- strtoi(value, base=16L)
if (temp>max_signed){ temp <- -(max_unsigned- temp) }

R floating point number precision being lost on coversion from character

I have a large floating point number as a character like so
x<-"5374761693.91823";
On doing
as.numeric(x);
I get the following output
5374761694
I would like to preserve the floating point nature of the number while casting.
use digits argument in print to see the actual number:
> print(as.numeric(x), digits=15)
[1] 5374761693.91823
options is another alternative:
> options(digits=16)
> as.numeric(x)
[1] 5374761693.91823
> # assignments
> options(digits=16)
> y <- as.numeric(x)
> y
[1] 5374761693.91823
z <- print(as.numeric(x), digits=15)
z

strtoi fails to convert string to integer, returns NA

32-bit binary string conversion from string to integer fails. See below
strtoi("10101101100110001110011001111111", base=2)
# [1] NA
Any ideas what the problem might be ?
It looks like strtoi cannot handle numbers greater than 2^31:
strtoi("1111111111111111111111111111111", base=2L)
# [1] 2147483647
strtoi("10000000000000000000000000000000", base=2L)
# [1] NA
which is the maximum integer my machine (and probably yours) can handle for an integer:
.Machine$integer.max
# [1] 2147483647
Note that the documentation does warn about overflow (from ?strtoi):
Values which cannot be interpreted as integers or would overflow are returned as NA_integer_.
What you can do is write your own function that returns the output as a numeric instead of an integer:
convert <- function(x) {
y <- as.numeric(strsplit(x, "")[[1]])
sum(y * 2^rev((seq_along(y)-1)))
}
convert("1111111111111111111111111111111")
# [1] 2147483647
convert("10000000000000000000000000000000")
# [1] 2147483648

Resources