计算一组字符的重复次数

时间:2017-01-16 11:50:05

标签: r

如何计算向量中一组字符的重复次数?想象一下,由"A""B"组成的以下向量:

x <- c("A", "A", "A", "B", "B", "A", "A", "B", "A")

在此示例中,第一个集合将是从索引1到5的"A""B"的序列,第二个集合是"A""B"的序列从索引6到8,然后第三组是最后一个"A"

x <- c("A", "A", "A", "B", "B", # set 1
       "A", "A", "B",           # set 2
       "A")                     # set 3

如何为每组变量设置一个计数器?我需要一个这样的矢量:

c(1, 1, 1, 1, 1, 2, 2, 2, 3)  

谢谢

3 个答案:

答案 0 :(得分:11)

使用rle

x <- c("A", "A", "A", "B", "B", "A", "A", "B", "A")  
tmp <- rle(x)
#Run Length Encoding
#  lengths: int [1:5] 3 2 2 1 1
#  values : chr [1:5] "A" "B" "A" "B" "A"

现在更改值:

tmp$values <- ave(rep(1L, length(tmp$values)), tmp$values, FUN = cumsum) 

并反转运行长度编码:

y <- inverse.rle(tmp)
#[1] 1 1 1 1 1 2 2 2 3

答案 1 :(得分:4)

备选方案1。

cumsum(c(TRUE, diff(match(x,  c("A", "B"))) == -1))
# [1] 1 1 1 1 1 2 2 2 3

一步一步:

match(x,  c("A", "B"))
# [1] 1 1 1 2 2 1 1 2 1

diff(match(x,  c("A", "B")))
# [1]  0  0  1  0 -1  0  1 -1

diff(match(x,  c("A", "B"))) == -1
# [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE

c(TRUE, diff(match(x,  c("A", "B"))) == -1)
# [1]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE

备选方案2。

使用data.table::rleid

library(data.table)
cumsum(c(TRUE, diff(rleid(x) %% 2) == 1))
# [1] 1 1 1 1 1 2 2 2 3

一步一步:

rleid(x)
# [1] 1 1 1 2 2 3 3 4 5

rleid(x) %% 2
# [1] 1 1 1 0 0 1 1 0 1

diff(rleid(x) %% 2)
# [1]  0  0 -1  0  1  0 -1  1

diff(rleid(x) %% 2) == 1
# [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE

c(TRUE, diff(rleid(x) %% 2) == 1)
# [1]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE

答案 2 :(得分:2)

我们只能使用base R方法

x1 <- split(x, cumsum(c(TRUE, x[-1]!= x[-length(x)])))
x2 <- sapply(x1, `[`, 1)
as.numeric(rep(ave(x2, x2, FUN = seq_along), lengths(x1)))
#[1] 1 1 1 1 1 2 2 2 3