【问题标题】:Convert a Binary Sample in Number将二进制样本转换为数字
【发布时间】:2015-11-20 14:05:57
【问题描述】:

我有一个像这样的二进制样本:

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 中做到这一点?

【问题讨论】:

  • 你想用什么编程语言来实现这个?

标签: r binary numbers


【解决方案1】:

试试:

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)
  • 对于y减3的长度(因为每个数字需要4位),应用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

【讨论】:

    【解决方案2】:

    这是另一种方法:

    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)
    

    【讨论】:

      【解决方案3】:

      你也可以使用

      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】:

        因为您将 4 位二进制转换为十进制数,所以公式为:

        十进制 = x1 * 2^3 + x2 * 2^2 + x3 * 2^1 + x4 * 2^0

        这可以通过R用扫频乘法来实现

        dec &lt;- sum( X * c(8,4,2,1) )

        OR 向量乘法(如@Greg Snow 所示)。

        dec &lt;- 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
        

        【讨论】:

          猜你喜欢
          • 2020-04-28
          • 2021-02-24
          • 1970-01-01
          • 2014-11-07
          • 2013-11-08
          • 1970-01-01
          • 2010-10-16
          相关资源
          最近更新 更多