[英]Convert a Binary Sample in Number
我有这样的二进制示例:
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)
我想转换长度为4的所有序列,即:
我需要读取原始二进制样本并将所有可能的长度为4的序列转换为数字。
示例:序列0000将为1,序列0001将为2,序列0010将为3,...,序列1111将为16。
预期输出应该是由数字1,2,3,... 16形成的新样本,其长度与原始样本相同:
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)
我怎么能在R?
试试:
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
代码的工作原理如下:
z
转换为字符矢量( y
) strtoi
函数 strtoi
函数通过指定输入数字的基数来转换数字(此处为2,因为它是二进制)。 我们加1,因为二进制0000等于0而不是1。
注意:转换为字符是可选的,你可以直接做
sapply(1:(length(z)-3),function(x){strtoi(paste(z[x:(x+3)],collapse=''),2)+1})
使用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
这是另一种方法:
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)
你也可以用
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
因为您将4位二进制文件转换为十进制数,公式将为:
dec = x1 * 2 ^ 3 + x2 * 2 ^ 2 + x3 * 2 ^ 1 + x4 * 2 ^ 0
这可以通过R实现扫描乘法来实现
dec <- sum( X * c(8,4,2,1) )
或矢量乘法(如@Greg Snow所示)。
dec <- X %*% c(8,4,2,1)
最后,通过sapply
将这个计算模式应用于数组的每4个元素,然后整个代码如下。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.