在基地R
,这可以完成这项工作:
> df <- data.frame(var1=rep(c("A","B"), each=5), var2=LETTERS[1:5])
> head(df)
var1 var2
1 A A
2 A B
3 A C
4 A D
5 A E
6 B A
> df$id<-unlist(tapply(df$var2, df$var1, seq_along))
> head(df)
var1 var2 id
1 A A 1
2 A B 2
3 A C 3
4 A D 4
5 A E 5
6 B A 1
改为使用data.table
:
library(data.table)
> dt <- data.table(var1=rep(c("A","B"), each=5), var2=LETTERS[1:5])
> dt[, id:=seq_along(var2), by=var1]
> head(dt)
var1 var2 id
1: A A 1
2: A B 2
3: A C 3
4: A D 4
5: A E 5
6: B A 1
上述两种技术都需要您var1
并且var2
没有任何重复值。如果发生这种情况,您可以针对您的不同值执行上述操作df
(将这些不同值保存到tmp
中),然后将结果加入原始表:
> df <- data.frame(var1=rep(c("A","B"), each=5), var2=LETTERS[1:5])
> df <- rbind(df, df)
> df <- df[ order(df$var1, df$var2),]
> head(df)
var1 var2
1 A A
11 A A
2 A B
12 A B
3 A C
13 A C
> tmp <- unique(df)
> head(tmp)
var1 var2
1 A A
2 A B
3 A C
4 A D
5 A E
6 B A
> tmp$id<-unlist(tapply(tmp$var2, tmp$var1, seq_along))
> head(tmp)
var1 var2 id
1 A A 1
2 A B 2
3 A C 3
4 A D 4
5 A E 5
6 B A 1
> df <- merge(df, tmp)
> head(df,10)
var1 var2 id
1 A A 1
2 A A 1
3 A B 2
4 A B 2
5 A C 3
6 A C 3
7 A D 4
8 A D 4
9 A E 5
10 A E 5
我天堂没有提供加入(合并R
)的列,因为默认情况下它已经完成了所有具有通用名称的列(即var1
then var2
)。如果您需要指定:
merge(df, tmp, by=c("var1","var2")) # if the have same col names
merge(x=df, y=tmp, by.x=c("var1","var2"), by.y=c("var1","var2")) # if they don't. (not needed here)
或者,(现在才想到),不使用任何连接:
df$id <- tapply(df$var2, df$var1, function(x) as.numeric(factor(x)))