Reputation: 51
I have a binary sample like this :
Z = c(0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,1,0)
I would like to convert all the sequences of the length 4 in number, i.e :
I need to read my original binary sample and convert all the possible sequence of length 4 into numbers.
Example: The sequence 0000 will be 1, the sequence 0001 will be 2, the sequence 0010 will be 3, ..., the sequence 1111 will be 16.
The expected output should be a new sample formed by the numbers 1,2,3,...16 having the same length as the original sample :
Z = c(0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,1,0)
Z1 = c(2,3,6,12,8,15,14,11,5,10,3,11,6,12,8,15,14,11,6,11)
How can I do that in R ?
Upvotes: 3
Views: 135
Reputation: 2131
Because you transfer 4 bit binaries to decimal number, the formula will be:
dec = x1 * 2^3 + x2 * 2^2 + x3 * 2^1 + x4 * 2^0
And this can be implemented by R with sweep multiplication
dec <- sum( X * c(8,4,2,1) )
OR vector multiplication (as @Greg Snow shown).
dec <- X %*% c(8,4,2,1)
Finally, using this computational pattern to every 4 elements of array by sapply
, then the whole code as below .
Z <- c(0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,1,0)
Z.len <- length(Z)
# stand for 2^3, 2^2, 2^1, 2^0
Z.base <- c(8,4,2,1)
res1 <- sapply(1:(Z.len-3), FUN=function(x) sum(Z[x:(x+3)] * Z.base)+1 )
res2 <- sapply(1:(Z.len-3), FUN=function(x) (Z[x:(x+3)] %*% Z.base)+1 )
all.equal(res1, res2)
#[1] TRUE
res1
# [1] 2 3 6 12 8 15 14 11 5 10 3 6 11 6 12 8 15 14 11 6 11
Upvotes: 0
Reputation: 49640
Here is another approach:
Z <- c(0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,1,0)
Z.tmp <- embed(Z,4)
Z1 <- as.vector(Z.tmp %*% c(1,2,4,8) + 1)
Upvotes: 3
Reputation: 887251
You could also use
library(zoo)
library(compositions)
unbinary(rollapply(z,4, FUN= paste, collapse=''))+1L
#[1] 2 3 6 12 8 15 14 11 5 10 3 6 11 6 12 8 15 14 11 6 11
Upvotes: 2
Reputation: 3678
Try :
z<-c(0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,1,0)
y<-as.character(z)
z1<-sapply(1:(length(y)-3),function(x){strtoi(paste(y[x:(x+3)],collapse=''),2)+1})
[1] 2 3 6 12 8 15 14 11 5 10 3 6 11 6 12 8 15 14 11 6 11
The code works like this :
z
as a character vector (y
)strtoi
functionThe strtoi
function convert the number by specifying the base of the input number (here, 2 because it's binary). We add 1 because in binary 0000 equals 0 and not 1.
Note: the conversion to character is optional, you can directly do
sapply(1:(length(z)-3),function(x){strtoi(paste(z[x:(x+3)],collapse=''),2)+1})
it will also be faster to use vapply
:
vapply(1:(length(z)-3),function(x){strtoi(paste(z[x:(x+3)],collapse=''),2)+1},FUN.VALUE=1)
Unit: microseconds
expr min lq mean median uq max neval cld
vapply 206.866 209.111 214.3936 210.0735 211.356 338.362 100 a
sapply 230.278 231.882 234.0249 232.8440 234.128 273.897 100 b
Upvotes: 3