29

How to convert an integer number into binary vector using R?

For example :

number <- 11
[1] 1 0 1 1

what is the fastest possible method of conversion (using R code or some existing functions from packages) if I need to convert whole vector of numbers (minimum value = 0, maximum =300) into binary matrix ?

Follow the rabbit : base::intToBits

Qbik
  • 5,885
  • 14
  • 62
  • 93

11 Answers11

34

There's the intToBits function that converts any integer to a vector of 32 raws, so you can do this:

decimals <- c(3,5,11,4)
m <- sapply(decimals,function(x){ as.integer(intToBits(x))})
m

> m
      [,1] [,2] [,3] [,4]
 [1,]    1    1    1    0
 [2,]    1    0    1    0
 [3,]    0    1    0    1
 [4,]    0    0    1    0
 [5,]    0    0    0    0
 [6,]    0    0    0    0
 [7,]    0    0    0    0
 [8,]    0    0    0    0
 [9,]    0    0    0    0
[10,]    0    0    0    0
[11,]    0    0    0    0
[12,]    0    0    0    0
[13,]    0    0    0    0
[14,]    0    0    0    0
[15,]    0    0    0    0
[16,]    0    0    0    0
[17,]    0    0    0    0
[18,]    0    0    0    0
[19,]    0    0    0    0
[20,]    0    0    0    0
[21,]    0    0    0    0
[22,]    0    0    0    0
[23,]    0    0    0    0
[24,]    0    0    0    0
[25,]    0    0    0    0
[26,]    0    0    0    0
[27,]    0    0    0    0
[28,]    0    0    0    0
[29,]    0    0    0    0
[30,]    0    0    0    0
[31,]    0    0    0    0
[32,]    0    0    0    0
digEmAll
  • 56,430
  • 9
  • 115
  • 140
29

This SO post suggests the intToBits function. I define the function number2binary, which includes an argument noBits to control how many bits are returned. Standard is to return 32 bits.

number2binary = function(number, noBits) {
       binary_vector = rev(as.numeric(intToBits(number)))
       if(missing(noBits)) {
          return(binary_vector)
       } else {
          binary_vector[-(1:(length(binary_vector) - noBits))]
       }
    }

And for some examples:

> number2binary(11)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
> number2binary(11, 4)
[1] 1 0 1 1
Community
  • 1
  • 1
Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149
13

Try the CRAN package "binaryLogic"

library(binaryLogic)

as.binary(11)
[1] 1 0 1 1

as.binary(11, littleEndian=TRUE)
[1] 1 1 0 1

as.binary(42, n=16)
[1] 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0

as.binary(0:2, n=2)
[[1]]
[1] 0 0

[[2]]
[1] 0 1

[[3]]
[1] 1 0

as.binary(0xFF)
[1] 1 1 1 1 1 1 1 1

Also available: shift, rotate, graycode etc.

lemon
  • 131
  • 1
  • 2
  • 1
    binaryLogic was removed from CRAN – Cos May 03 '22 at 07:37
  • You can just pull the archived R code from the archive at https://cran.r-project.org/src/contrib/Archive/binaryLogic/ (or at github https://github.com/d4ndo/binaryLogic but I personally refuse to use devtools, so wouldn't install from there). – Dalton Bentley Aug 31 '22 at 14:23
8

You could use the following function for that, based on intToBit :

intToBitVect <- function(x){
  tmp <- rev(as.integer(intToBits(x)))
  id <- seq_len(match(1,tmp,length(tmp))-1)
  tmp[-id]
}

The first line converts the intToBits output to a numeric 0 and 1, and puts the order straight. The second line checks which values need to be retained, as follows:

  • check where the first 1 occurs using match. If there's no 1 to be found, you ask match to return the length of your tmp vector.
  • create a sequence (using seq_len) from 1 to the position previous to the first occurence of 1 in the tmp vector
  • drop all those positions in the tmp vector

To show it works :

> intToBitVect(11)
[1] 1 0 1 1
> intToBitVect(0)
[1] 0
Dmitriy Selivanov
  • 4,545
  • 1
  • 22
  • 38
Joris Meys
  • 106,551
  • 31
  • 221
  • 263
7

A solution I have found in "The R Book" by M. J. Crawley is the following function:

binary <- function(x) {
  i <- 0
  string <- numeric(32)
  while(x > 0) {
    string[32 - i] <- x %% 2
    x <- x %/% 2
    i <- i + 1 
  }
  first <- match(1, string)
  string[first:32] 
}
4

And another:

toBits <- function (x, nBits = 8){
   tail(rev(as.numeric(intToBits(x))),nBits)
}
Joe
  • 1,455
  • 2
  • 19
  • 36
3
intToBin <- function(x){
  if (x == 1)
    1
  else if (x == 0)
    NULL
  else {
   mod <- x %% 2
   c(intToBin((x-mod) %/% 2), mod)
  }
}

So intToBin(10) returns

[1] "1" "0" "1" "0"

And if you want string instead of vector

> paste0(intToBin(10), collapse = "")
[1] "1010"
schwannden
  • 31
  • 2
2

If you want to return a binary sequence, i.e. a vector of 1's and 0's, then this function will do that for you, but it can only take 1 number at a time.

dectobin <- function(y) {
  # find the binary sequence corresponding to the decimal number 'y'
  stopifnot(length(y) == 1, mode(y) == 'numeric')
  q1 <- (y / 2) %/% 1
  r <- y - q1 * 2
  res = c(r)
  while (q1 >= 1) {
   q2 <- (q1 / 2) %/% 1
   r <- q1 - q2 * 2
   q1 <- q2
   res = c(r, res)
  }
  return(res)
}
epwalsh
  • 21
  • 2
2

You don't actually need to call any function to get this - modular arithmetic alone can give the answer.

int_to_binary <- function(num, pow) {
  if(2^(pow + 1) - 1 < num) stop("Use a higher values of 'pow'")
  num %/% (2^(pow:0)) %% 2
}
Melissa Key
  • 4,476
  • 12
  • 21
1

Here is an Rcpp implementation.

In Rstudio, save the following code in a file, say binary.cpp, then type Source.

//************************
// binary.cpp 
#include <RcppArmadillo.h>

//' @Title get the binary representation of a positive integer
// [[Rcpp::depends(RcppArmadillo)]]
//[[Rcpp::export]]
void intToBinary(int n, arma::vec& a ) {
  for(int i=0;n>0;i++){
    a[i]=n%2;
    n=n/2;
  }
}
//************************

If Source went smooth, from the R console type

> a <- rep(0,10) # needed to store the binary representation
> myInt <- 5 # to be converted to binary form
> intToBinary(myInt, a)
> rev(a) # print in the usual form
utobi
  • 279
  • 8
  • 16
0

if your integer is n, then let

bits=floor(log(n)/log(2))
powers = 2^(bits:0)
nBin = bitwAnd(n,powers)/powers

nBin is your desired binary sequence. You may also choose a fixed bit length.