我有这样的二进制样本:
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?中做到这一点?
答案 0 :(得分:3)
尝试:
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
答案 1 :(得分:3)
这是另一种方法:
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)
答案 2 :(得分:2)
您也可以使用
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
答案 3 :(得分:0)
因为您将4位二进制数转换为十进制数,所以公式为:
dec = x1 * 2 ^ 3 + x2 * 2 ^ 2 + x3 * 2 ^ 1 + x4 * 2 ^ 0
这可以通过R实现扫描乘法
来实现 dec <- sum( X * c(8,4,2,1) )
OR向量乘法(显示为@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