3

テストデータセットを検討すると、

dat=data.frame(name=c('A','A','B','C','C','C'),val=c(1,1,2,2,3,2))

name val
A   1
A   1
B   2
C   2
C   3
C   2

この出力を取得するための最も効率的な方法は何でしょうか

name val
A   1
A-1   1
B   2
C   2
C-1   3
C-2   2

したがって、重複をカスタム識別子でマークするだけです。を使用して共通の識別子でそれらをマークすることを考えることができますがpaste(dat[which(duplicated(dat$name)),1],"-1",sep='')、これは複製されたすべてのものの前に「-1」を置くだけです。アイテムが3回目に表示される場合は、「-2」などのマークを付けてください。

乾杯

4

3 に答える 3

9

使用make.unique

transform(dat,name=make.unique(as.character(name),sep="-"))
  name val
1    A   1
2  A-1   1
3    B   2
4    C   2
5  C-1   3
6  C-2   2
于 2013-02-07T17:19:32.340 に答える
3

それはあなたが求めていたものとは正確には異なりますが、これを試すことができます:

within(dat, {
  Name <- paste(name, as.numeric(ave(as.character(name), 
                                     name, FUN = seq_along)) - 1,
                sep = "-")
  rm(name)
})
#   val Name
# 1   1  A-0
# 2   1  A-1
# 3   2  B-0
# 4   2  C-0
# 5   3  C-1
# 6   2  C-2

または、少し変更を加えて:

within(dat, {
  name <- as.character(name)
  Name <- as.numeric(ave(name, name, FUN = seq_along)) - 1
  Name <- ifelse(Name == 0, name, paste(name, Name, sep = "-"))
  rm(name)
})
#   val Name
# 1   1    A
# 2   1  A-1
# 3   2    B
# 4   2    C
# 5   3  C-1
# 6   2  C-2
于 2013-02-07T17:12:30.430 に答える
3
library(plyr)

ddply( dat, .(name), function(d) {
    d$newname <- paste( d$name, cumsum(duplicated(d$name)), sep="-" )
    d
  })

結果:

  name val newname
1    A   1     A-0
2    A   1     A-1
3    B   2     B-0
4    C   2     C-0
5    C   3     C-1
6    C   2     C-2
于 2013-02-07T17:08:42.537 に答える