R:按组创建数字序列并按特定条件启动序列

时间:2014-06-18 00:03:53

标签: r grouping sequence

我想创建一个新变量Number,它在一个特定条件下(在这种情况下,当Percent> 5时)从组ID开始依次生成数字。

groupID <- c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3)
Percent <- c( 3, 4, 5, 10, 2, 1, 6, 8, 4, 8, 10, 11)

Number <- ifelse (Percent < 5, 0, 1:4)

我明白了:

> Number
[1] 0 0 3 4 0 0 3 4 0 2 3 4

但我想:

    0 0 1 2 0 0 1 2 0 1 2 3

我没有在ifelse语句中包含groupID变量,而是使用1:4,因为每个groupID中总有4行。

有任何建议或线索吗?谢谢!

3 个答案:

答案 0 :(得分:4)

 ave(Percent, groupID, FUN=function(x) cumsum(x>=5))
[1] 0 0 1 2 0 0 1 2 0 1 2 3

对于以下评论中的示例,这是我的替代逻辑测试cumsum() - 编辑:

ave(Percent, groupID, FUN=function(x) cumsum(seq_along(x)>= which(x >=5)[1]) )

答案 1 :(得分:2)

它很丑陋并且会发出警告,但它可以让你得到你想要的东西:

ave(Percent,groupID,FUN=function(x) {x[x<5] <- 0; x[x>=5] <- 1:4; x} )
#[1] 0 0 1 2 0 0 1 2 0 1 2 3

@ BondedDust在下面使用cumsum的答案几乎肯定更合适。

如果您的数据在每个组中并不总是按升序排列,您还可以替换所有>=5值,例如:

Percent <- c( 3, 5, 4, 10, 2, 1, 6, 8, 4, 8, 10, 11)
ave(Percent, list(groupID,Percent>=5), FUN=function(x) cumsum(x>=5))
#[1] 0 1 0 2 0 0 1 2 0 1 2 3

答案 2 :(得分:1)

试试这个:

ID <- c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3)
Percent <- c( 3, 4, 5, 10, 2, 1, 6, 8, 4, 8, 10, 11)


Number <- Percent >= 5

result = lapply(seq_along(Number), function(i){
    if( length(which(! Number[1:i]) ) == 0){start = 1}
    else {start =max(which(! Number[1:i]) )}

    sum( Number[start : i])

  })

> unlist(result)
[1] 0 0 1 2 0 0 1 2 0 1 2 3