我希望在数据框中添加一列,对于列组合的子集中的每个元素,写入该元素的等级。
下面的代码解决了这个问题,但我希望以更高的内存和CPU效率的方式来解决这个问题。
## using the plyr package
library(plyr)
## example data
var1 = c(1,1,1,1,2,2,1,5,6,7,1,9,10)
var2 = c("a","a","a","b","b", "b","c","c","c","c","a","a","a" )
ex1 <- data.frame( var1, var2 )
## easy but inefficient solution
ex2 <- ddply( ex1, c("var1", "var2"), transform, run = 1:length(var1) )
print(ex2)
输出看起来像这样(这就是我想要的)
"var1" "var2" "run"
1 "a" 1
1 "a" 2
1 "a" 3
1 "a" 4
1 "b" 1
1 "c" 1
2 "b" 1
2 "b" 2
5 "c" 1
6 "c" 1
7 "c" 1
9 "a" 1
10 "a" 1
组合var1 == 1&amp; var2 ==“a”发生了4次。在该子组中,ddply计算每个元素的等级,并将该等级保存在该元素的同一行中。组合第一次运行[1]得到“1”,第二次运行[2]得到“2”等等......
在我的例子中,结果由ddply函数重新排序,但这并不重要。
答案 0 :(得分:3)
你可以使用dplyr
这样做:
require(dplyr)
ex1 %>% group_by(var1, var2) %>% mutate(run = 1:n()) %>% arrange(var1, var2)
# var1 var2 run
#1 1 a 1
#2 1 a 2
#3 1 a 3
#4 1 a 4
#5 1 b 1
#6 1 c 1
#7 2 b 1
#8 2 b 2
#9 5 c 1
#10 6 c 1
#11 7 c 1
#12 9 a 1
#13 10 a 1
arrange
只是按照您想要的结果顺序得到它。
我认为你可以使用data.table
来做到这一点,但我不确定这是否是最惯用的数据。表格方法:
require(data.table)
setDT(ex1)[,run:=1:.N, by=list(var1, var2)]
# var1 var2 run
#1: 1 a 1
#2: 1 a 2
#3: 1 a 3
#4: 1 b 1
#5: 2 b 1
#6: 2 b 2
#7: 1 c 1
#8: 5 c 1
#9: 6 c 1
#10: 7 c 1
#11: 1 a 4
#12: 9 a 1
#13: 10 a 1
正如@DavidArenburg在评论中所建议的那样,最好使用:
setDT(ex1)[,run:=seq_len(.N), by=list(var1, var2)]
用于data.table
方法。感谢您的评论!
答案 1 :(得分:2)
ave
适用于此:
ex1$run <- ave(ex1$var1, list(ex1$var1, ex1$var2), FUN=seq_along)
ex1
var1 var2 run
1 1 a 1
2 1 a 2
3 1 a 3
4 1 b 1
5 2 b 1
6 2 b 2
7 1 c 1
8 5 c 1
9 6 c 1
10 7 c 1
11 1 a 4
12 9 a 1
13 10 a 1
请注意,行不会重新排序。