【问题标题】:R: How to count number of 1 and write to vectorR:如何计算 1 的数量并写入向量
【发布时间】:2014-12-01 05:45:25
【问题描述】:

我的信号向量看起来像这样:

a

我将计算一个 1 在一个 raw 中出现的频率,并将其写入向量 b,例如对于向量 a 它应该导致:

b
5,2,1,1,1,1,3

原因是我将绘制一个直方图,显示事件长度的分布。也许 R 中已经有一个函数可以做到这一点?否则使用if循环?

干杯 格雷格

【问题讨论】:

标签: r


【解决方案1】:

你可以试试rle(注意这些解决方案也来自base R

with(rle(a), lengths[!!values])
#[1] 5 2 1 1 1 1 3

或者

unname(table(cumsum(c(1,abs(diff(a)))))[c(TRUE, FALSE)])
#[1] 5 2 1 1 1 1 3

如果向量不是二进制的

with(rle(a), lengths[values==1])
#[1] 5 2 1 1 1 1 3

或者

unname(table(cumsum(c(1,abs(diff(a==1)))))[c(TRUE, FALSE)])

编辑

如果向量以 1 以外的数字开头。例如02(正如@Ananda Mahto 在 cmets 中提到的)

 a[1] <- 2
 a1 <- a[which(a==1)[1]:length(a)]
 unname(table(cumsum(c(1,abs(diff(a1==1)))))[c(TRUE, FALSE)])
 #[1] 4 2 1 1 1 1 3
 with(rle(a), lengths[values==1])
 #[1] 4 2 1 1 1 1 3


 

或者

with(rle(a == 1), lengths[values]) # from @Richard Scriven's comments

【讨论】:

  • 另一种方式with(rle(a == 1), lengths[values])
  • @RichardScriven 谢谢,也许少了一个字符。
  • cumsum 方法依赖于第一个值,对吧?
  • @AnandaMahto 谢谢,你是对的。这取决于第一个值
【解决方案2】:

无耻插件,但由于您只处理 1 和 0,您还可以使用我的“SOfun”包 (only on GitHub) 中的 TrueSeq

TrueSeq 的作用如下:

library(SOfun)
TrueSeq(as.logical(a))
#  [1] 1 1 1 1 1 0 0 0 0 2 2 0 0 0 3 0 4 0 5 0 6 0 0 0 0 0 0 0 0 0 0 0 7 7 7

记住这一点,您可以在输出中使用tabulate,因为这样会丢弃零:

tabulate(TrueSeq(as.logical(a)))
# [1] 5 2 1 1 1 1 3

【讨论】:

    【解决方案3】:

    base R 的另一个解决方案:

    count1<-strsplit(paste(a,collapse=""),"0")[[1]]
    b<-nchar(count1[count1!=""])
    
    > b
    [1] 5 2 1 1 1 1 3
    

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 2016-06-08
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      相关资源
      最近更新 更多