

1,1,2,3,3,3,5,5,7,7,7,7のように欠番があり、かつ各数字の数が異なるベクトルがあった場合に、  
1,1,2,3,3,3,4,4,5,5,5,5のように欠番を詰めて数字が小さい順に要素を書き換える方法がどうしてもわかりません。  
お分かりになる方、どうかお助けいただきますようお願いいたします。

ちなみに無理やり書いてみると以下のようになりましたが、とても実用ベースでは使えないような汚いコードです。

[code]

    vec <- c(1,1,2,3,3,3,5,5,7,7,7,7)
    
    # まず同じ数ごとにリストに格納する
    testlist <- list()
    for (i in vec){
      testlist[[i]] <- vec[vec == i]
    }
    testlist #  1,2,3,5,7番目の要素に数値、4,6番目にはNULLが入ったリスト
    
    #  NULLの部分を削除して詰める
    newlist <- testlist[unique(vec)]
    #  リストの各要素の名前を続き番号でリネーム
    names(newlist) <- 1:length(newlist) #  リストの要素はvecのまま欠番を保持しているがnamesは続き番号
    
    #  newlistのnamesすなわち続き番号を取り出して、その番地のリスト要素の
    #  中身を続き番号と同じになるように書き換える
    finallist <- list()
    for (i in 1:length(newlist)){
      tmp <- names(newlist)[i]
      finallist[[i]] <- rep(tmp, length(newlist[[i]]))
    }
    finallist
    newvec <- unlist(finallist)
    newvec <- as.numeric(newvec)
    newvec    # 1,1,2,3,3,3,4,4,5,5,5,5
    
[/code]


CC BY-SA 4.0
2019-04-04T14:40:12.487
53922
2019-04-05T06:03:31.383
2019-04-04T15:09:19.400
3605
32786
question
r
ベクトルの欠番を詰めて欠番が無いように要素を置換する方法（R言語）


こちらで如何でしょうか。役に立てれば幸いです。

[code]

    vec <- c(1,1,2,3,3,3,5,5,7,7,7,7)
    
    target1 <- setdiff(1:max(vec), unique(vec))
    
    for(i in 1:length(target1)){
    vec[target1[i]<=vec] <- vec[target1[i]<=vec]-1
    }
    
[/code]

追記  
すみません、既にエレガントな回答来てましたね。失礼しました。


CC BY-SA 4.0
2019-04-05T00:55:59.503
53928
2019-04-05T01:18:38.110
2019-04-05T01:18:38.110
3060
32789
53922
answer


`vec`が長いときはこれがよいと思います。

[code]

    cumsum(tabulate(vec)>0)[vec]
    
[/code]


CC BY-SA 4.0
2019-04-05T03:06:52.717
53930
2019-04-05T03:06:52.717
9464
53922
answer


1から始まる場合に限定すれば、

[code]

    as.numeric(as.factor(vec))
    
[/code]

とかどうですかね。


CC BY-SA 4.0
2019-04-05T05:12:45.520
53932
2019-04-05T06:03:31.383
2019-04-05T06:03:31.383
754
28031
53922
answer