为每个组计算排名

6

我有一个带有类型和值的df(数据框)。我想按照typex的顺序对它们进行排名,并计算其他行中比行nx值更高(列pos)的数量。

例如:

df <- data.frame(type = c("a","a","a","b","b","b"),x=c(1,77,1,34,1,8))
# for type a row 3 has a higher x than row 1 and 2 so has a pos value of 2

我可以通过以下方式完成这个任务:
library(plyr)
df <- data.frame(type = c("a","a","a","b","b","b"),x=c(1,77,1,34,1,8))
df <- ddply(df,.(type), function(x) x[with(x, order(x)) ,])
df <- ddply(df,.(type), transform, pos = (seq_along(x)-1) )

     type  x pos
1    a  1   0
2    a  1   1
3    a 77   2
4    b  1   0
5    b  8   1
6    b 34   2

但是这种方法没有考虑到类型 a 的第1行和第2行之间的关系。最简单的获取输出结果的方法是什么,使得连结具有相同的值,例如:

     type  x pos
 1    a  1   0
 2    a  1   0
 3    a 77   2
 4    b  1   0
 5    b  8   1
 6    b 34   2
1个回答

8
ddply(df,.(type), transform, pos = rank(x,ties.method ="min")-1)

  type  x pos
1    a  1   0
2    a 77   2
3    a  1   0
4    b 34   2
5    b  1   0
6    b  8   1

只需使用min函数,它使得序列中发现的相同元素取最小值作为排名。否则,对于我的相同元素,它们都将具有值1。 - user1320502
1
或者,如果坚持使用基本的R语言,但采用与上述方法相同的方式,则可以使用以下代码:within(df, {pos <- ave(x, type, FUN=function(x) rank(x, ties.method = "min")-1)})。如果使用"data.table"(假设数据表命名为"DT"),则可以使用以下代码:DT[, list(x, pos = rank(x, ties.method="min")-1), by = "type"] - A5C1D2H2I1M1N2O1R2T1
1
@AnandaMahto DT[,pos:=rank(x,ties.method ="min")-1, by = type] - Roland
是的,确实如此。我忘记了按引用分配。我会把它归咎于印度深夜。 - A5C1D2H2I1M1N2O1R2T1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接