【问题标题】:r Counting occurences of specific number between specific numberr 计算特定数字之间特定数字的出现次数
【发布时间】:2018-04-12 13:12:45
【问题描述】:

我有一个矩阵,其中每个元素都是 0 或 1。 我想获得每行中连续出现 0 的频率,因为序列中的最后一个 0 后面跟着一个 1。

例如:

一行有:0, 1, 0, 1, 0, 0

预期的结果应该是:

连续的 0 长度:1

频率:2

另一行有:0, 1, 0, 0, 1, 0, 0, 0, 1

预期结果:

连续 0 的长度:1 2 3

频率:1 1 1

然后,另一个目标是对相同长度的频率求和,以便知道有多少次单个 0 后面跟着一个 1,两个连续的 0 后面跟着一个 1 等等。

这是我想在其上应用例程的示例矩阵:

m = matrix( c(1, 0, 1, 1, 1, 1, 0, 0, 0,  0,
      1, 1, 1, 1, 0, 1, 0, 0, 0,  0,
      1, 0, 0, 0, 1, 1, 1, 0, 0,  0,
      0,  1, 0, 0, 0, 0, 0, 1, 1, 1,
      1, 1, 1, 0, 0, 0, 0, 0, 1,  0,
      1, 0, 0, 0, 0, 0, 1, 1, 0,  0),

      ncol = 10, nrow = 6, byrow=TRUE)

预期的结果应该类似于下面的矩阵:

result = matrix( c(3, 0, 1, 0, 3, 0, 0, 0, 0, 0), ncol=10, nrow=1)
colnames(result) <- c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")

其中列名是连续 0 的长度(后跟 1),矩阵条目是相应的频率。

请注意,我有一个非常大的数据矩阵,如果可能的话,我想避免循环。感谢您的任何提示、cmets 和建议。

【问题讨论】:

  • 您能否展示您展示的示例的预期输出
  • 类似这样的东西:apply(m, 1, rle)?
  • 我尝试了 rle() 但我认为,在这个版本中,很难获得预期的输出表。

标签: r matrix frequency


【解决方案1】:

使用基本函数。复杂之处在于您要丢弃不以 1 结尾的尾随零。

解释。

set.seed(13L)
numRows <-  10e4
numCols <- 10
m <- matrix(sample(c(0L, 1L), numRows*numCols, replace=TRUE),
    byrow=TRUE, ncol = numCols, nrow = numRows)
#add boundary conditions of all zeros and all ones
m <- rbind(rep(0L, numCols), rep(1L, numCols), m)
#head(m)

rStart <- Sys.time()
lens <- unlist(apply(m, 1, function(x) {
    #find the position of the last 1 while handling boundary condition of all zeros
    idx <- which(x==1)
    endidx <- if (length(idx) == 0) length(x) else max(idx)
    beginidx <- if(length(idx)==0) 1 else min(idx)

    #tabulate the frequencies of running 0s.
    runlen <- rle(x[beginidx:endidx])
    list(table(runlen$lengths[runlen$values==0]))
}))

#tabulating results
res <- aggregate(lens, list(names(lens)), FUN=sum)
ans <- setNames(res$x[match(1:ncol(m), res$Group.1)], 1:ncol(m))
ans[is.na(ans)] <- 0
ans
#     1      2      3      4      5      6      7      8      9     10 
#100108  43559  18593   7834   3177   1175    387    103      0    106 

rEnd <- Sys.time()
print(paste0(round(rEnd - rStart, 2), attr(rEnd - rStart, "units")))
#[1] "27.67secs"

请告诉我在大型矩阵上运行后的性能。

【讨论】:

  • 非常感谢您的工作。虽然结果让我吃惊。我将您的代码应用于我的小示例“m”矩阵我得到了结果:
  • 如果我对您的解释正确,您是按行输入值,因此您需要在数据集中传入 byrow=TRUE。在控制台中打印 m 以查看您最终得到的矩阵。
  • > ans 6 4 1 2 0 0 0 0 0 0 ;这意味着在矩阵中 6 次有一个 0 后跟一个 1 ,4 次两个连续的零,到目前为止。但是,在我的示例中,结果应该像上面那样。 (单个 0 出现 3 次后接 1,连续 2 个 0 后接 1 出现 0 次,连续 3 个 0 后接 1 出现 1 次,依此类推)
  • 我在添加进一步的传导时遇到了问题:零链不仅必须跟在 1 之后,还必须在 1 之后开始。修改上面的解决方案我在apply() 命令中遇到问题,尤其是table() 不再起作用:
  • lens的行中添加上述解决方案:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 1970-01-01
  • 2019-10-07
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多