40

データフレームの各グループ内で一意の ID 番号を生成するにはどうすればよいですか? 「personid」でグループ化されたデータは次のとおりです。

personid date measurement
1         x     23
1         x     32
2         y     21
3         x     23
3         z     23
3         y     23

「personid」で定義された各サブセット内の各行に一意の値を持つ id 列を追加したいと思います。常に1. これは私の望ましい出力です:

personid date measurement id
1         x     23         1
1         x     32         2
2         y     21         1
3         x     23         1
3         z     23         2
3         y     23         3

助けていただければ幸いです。

4

6 に答える 6

37

dplyr便利な関数row_numberとを使用したいくつかの代替手段n

library(dplyr)
df %>% group_by(personid) %>% mutate(id = row_number())
df %>% group_by(personid) %>% mutate(id = 1:n())
df %>% group_by(personid) %>% mutate(id = seq_len(n()))
df %>% group_by(personid) %>% mutate(id = seq_along(personid))

getanIDパッケージから使用することもできますsplitstackshape。入力データセットは として返されることに注意してくださいdata.table

getanID(data = df, id.vars = "personid")
#    personid date measurement .id
# 1:        1    x          23   1
# 2:        1    x          32   2
# 3:        2    y          21   1
# 4:        3    x          23   1
# 5:        3    z          23   2
# 6:        3    y          23   3
于 2015-06-02T12:33:22.813 に答える
31

引数 を持つ誤解を招く名前のave()関数は、列が厳密に順序付けされていなくFUN=seq_alongても、これをうまく実行します。personid

df <- read.table(text = "personid date measurement
1         x     23
1         x     32
2         y     21
3         x     23
3         z     23
3         y     23", header=TRUE)

## First with your data.frame
ave(df$personid, df$personid, FUN=seq_along)
# [1] 1 2 1 1 2 3

## Then with another, in which personid is *not* in order
df2 <- df[c(2:6, 1),]
ave(df2$personid, df2$personid, FUN=seq_along)
# [1] 1 1 1 2 3 2
于 2012-08-16T22:29:33.550 に答える
16

Using data.table, and assuming you wish to order by date within the personid subset

library(data.table)
DT <- data.table(Data)

DT[,id := order(date), by  = personid]

##    personid date measurement id
## 1:        1    x          23  1
## 2:        1    x          32  2
## 3:        2    y          21  1
## 4:        3    x          23  1
## 5:        3    z          23  3
## 6:        3    y          23  2

If you wish do not wish to order by date

DT[, id := 1:.N, by = personid]

##    personid date measurement id
## 1:        1    x          23  1
## 2:        1    x          32  2
## 3:        2    y          21  1
## 4:        3    x          23  1
## 5:        3    z          23  2
## 6:        3    y          23  3

Any of the following would also work

DT[, id := seq_along(measurement), by =  personid]
DT[, id := seq_along(date), by =  personid]

The equivalent commands using plyr

library(plyr)
# ordering by date
ddply(Data, .(personid), mutate, id = order(date))
# in original order
ddply(Data, .(personid), mutate, id = seq_along(date))
ddply(Data, .(personid), mutate, id = seq_along(measurement))
于 2012-08-16T23:12:00.877 に答える
7

これには定型のコマンドがあると思いますが、思い出せません。だからここに1つの方法があります:

> test <- sample(letters[1:3],10,replace=TRUE)
> cumsum(duplicated(test))
 [1] 0 0 1 1 2 3 4 5 6 7
> cumsum(duplicated(test))+1
 [1] 1 1 2 2 3 4 5 6 7 8

これduplicatedは、論理ベクトルを返すために機能します。 cumsum数値ベクトルをevalueするため、論理は数値に強制変換されます。

必要に応じて、結果を新しい列としてdata.frameに保存できます。

dat$id <- cumsum(duplicated(test))+1
于 2012-08-16T22:12:28.370 に答える
5

データが という名前の data.frame にあると仮定するとData、これでうまくいきます。

# ensure Data is in the correct order
Data <- Data[order(Data$personid),]
# tabulate() calculates the number of each personid
# sequence() creates a n-length vector for each element in the input,
# and concatenates the result
Data$id <- sequence(tabulate(Data$personid))
于 2012-08-16T22:24:26.347 に答える
3

使用できますsqldf

df<-read.table(header=T,text="personid date measurement
1         x     23
1         x     32
2         y     21
3         x     23
3         z     23
3         y     23")

library(sqldf)
sqldf("SELECT a.*, COUNT(*) count
       FROM df a, df b 
       WHERE a.personid = b.personid AND b.ROWID <= a.ROWID 
       GROUP BY a.ROWID"
)

#  personid date measurement count
#1        1    x          23     1
#2        1    x          32     2
#3        2    y          21     1
#4        3    x          23     1
#5        3    z          23     2
#6        3    y          23     3
于 2012-08-17T03:21:40.007 に答える