Using R gmp big numbers in a dataframe/tibble and plot

Viewed 67

I have some computations that involve calculations with very large numbers, and understand that the package gmp allows handling of arbitrarily large numbers. However, if I try to use the numbers in a tibble or plot them, R gives the following errors, even for numbers the size of which R can handle, so I know that the simple size of the number is not the problem:

Error in [<-.data.frame(*tmp*, unname, value = list(a = as.raw(c(0x03, : replacement element 1 has 3 rows, need 40

and for plotting:

Don't know how to automatically pick scale for object of type bigz. Defaulting to continuous. Error: Aesthetics must be either length 1 or the same as the data (40): x

The following reprex should produce the same errors:

library(tidyverse)
library(gmp)

test <- tibble(a = c(as.bigz("1000000"), as.bigz("1000000"), as.bigz("1000000")))

test <- mutate(test,
               b = a + 50000) 

I can see that the calculations have in fact worked:

test$b

But get errors when trying to just look at the tibble or plot the numbers:

test

ggplot(data = test) +
  geom_point(aes(x = b, y = 1))

I assume the problem is something to do with the class of the bigz, but don't know how to solve it.

1 Answers

We can wrap it in a list, loop over the list and do the transformation

library(dplyr)
library(gmp)
library(purrr)
test <- tibble(a = list(as.bigz("1000000"), as.bigz("1000000"), 
        as.bigz("1000000"))) %>% 
     mutate(b = map(a, ~ .x + 50000)) 

-output

> test
# A tibble: 3 × 2
  a           b          
  <list>      <list>     
1 <bigz [16]> <bigz [16]>
2 <bigz [16]> <bigz [16]>
3 <bigz [16]> <bigz [16]>
> test$b
[[1]]
Big Integer ('bigz') :
[1] 1050000

[[2]]
Big Integer ('bigz') :
[1] 1050000

[[3]]
Big Integer ('bigz') :
[1] 1050000

Not sure if ggplot can accept the bigz vector. But, the list can be converted to a vector and use plot from base R

test <- tibble(a = list(as.bigz("1000000"), as.bigz("1000000"), 
        as.bigz("1000000"))) %>% 
     mutate(b = map2(a, seq(50000, length.out = n(), by = 10000), ~ .x + .y))
plot(do.call(c, test$b), y = rep(1, nrow(test)))
Related