2017-09-01 70 views
0

对于这样一个数据帧:编号行至n中的数据帧

cat  val 
1 aaa 0.05638315 
2 aaa 0.25767250 
3 aaa 0.30776611 
4 aaa 0.46854928 
5 aaa 0.55232243 
6 bbb 0.17026205 
7 bbb 0.37032054 
8 bbb 0.48377074 
9 bbb 0.54655860 
10 bbb 0.81240262 
11 ccc 0.28035384 
12 ccc 0.39848790 
13 ccc 0.62499648 
14 ccc 0.76255108 
15 ccc 0.88216552 

我希望有一个分配的重复序列号,以行组明智像我分配号码只为1至3和那么序列在同一组中再次从1开始:

cat  val num 
1 aaa 0.05638315 1 
2 aaa 0.25767250 2 
3 aaa 0.30776611 3 
4 aaa 0.46854928 1 
5 aaa 0.55232243 2 
6 bbb 0.17026205 1 
7 bbb 0.37032054 2 
8 bbb 0.48377074 3 
9 bbb 0.54655860 1 
10 bbb 0.81240262 2 
11 ccc 0.28035384 1 
12 ccc 0.39848790 2 
13 ccc 0.62499648 3 
14 ccc 0.76255108 1 
15 ccc 0.88216552 2 

我该如何实现它?

回答

2

这里是一个典型的分裂/应用/结合的方法:

df <- unsplit(lapply(split(df, df$cat), function(x) 
       cbind(x, id = rep(1:3, length.out = nrow(x)))), df$cat) 

# cat  val id 
# 1 aaa 0.05638315 1 
# 2 aaa 0.25767250 2 
# 3 aaa 0.30776611 3 
# 4 aaa 0.46854928 1 
# 5 aaa 0.55232243 2 
# 6 bbb 0.17026205 1 
# 7 bbb 0.37032054 2 
# 8 bbb 0.48377074 3 
# 9 bbb 0.54655860 1 
# 10 bbb 0.81240262 2 
# 11 ccc 0.28035384 1 
# 12 ccc 0.39848790 2 
# 13 ccc 0.62499648 3 
# 14 ccc 0.76255108 1 
# 15 ccc 0.88216552 2 

而一个dplyr替代:

library(dplyr) 
df %>% group_by(cat) %>% mutate(id = rep(1:3, length.out = n())) 

和a data.table替代,也:`AVE(DAT $ VAL,DAT $猫,FUN =函数(X)代表(1:

library(data.table) 
setDT(df) 
df[, id := rep(1:3, length.out = .N), by = cat] 
用`ave`
+0

另外3,length.out =长度(X)))'。 – lmo

0

这应该可以做到。您可以在data.frame中获取唯一的猫,提取相应的行,然后附加从1开始的整数的数字向量,包括序列中的值(1,2,3)。每只猫记录1次。

df <- data.frame(cat=c(rep("aaa", 5), rep("bbb", 2), rep("ccc", 4), rep("ddd", 7)), 
       val = rnorm(n = 18)) 

df$num <- do.call(c, lapply(unique(df$cat), (function(i){ 
    slice <- df[df$cat==i,] 
    rep(1:3, 1+as.integer(nrow(slice)/3))[1:nrow(slice)] 
}))) 

最终的结果是以下

cat   val num 
1 aaa -0.20791826 1 
2 aaa 1.95733315 2 
3 aaa 1.01099852 3 
4 aaa 0.25355751 1 
5 aaa 0.70946906 2 
6 bbb 1.60555603 1 
7 bbb -0.05718921 2 
8 ccc 0.13465897 1 
0

这里是一个解决方案。虽然有一个警告,我觉得很优雅的简洁:

df=data.frame(cat=rep(letters[1:3],each=5),val=rnorm(3*5)) 
df[,"n"] <- tapply(df[,"val"],df[,"cat"],function(vec) rep.int(1:3,times=ceiling(length(vec)/3))[1:length(vec)]) 
df 

与结果

> df 
    cat   val n 
1 a -0.01160222 1 
2 a 0.13296221 2 
3 a -0.19907366 3 
4 a -0.52969178 1 
5 a 0.05834779 2 
6 b 1.06572206 1 
7 b 1.23418529 2 
8 b -2.53532404 3 
9 b -0.77518265 1 
10 b -1.35705148 2 
11 c -1.16828739 1 
12 c -0.32130593 2 
13 c 0.98217935 3 
14 c 0.31917671 1 
15 c 0.89867657 2