Reputation: 389
Newbie to R, I've tried Googling but I'm failing find a solution.
Here's my data frame:
Name Value
Bob 50
Mary 55
John 51
Todd 50
Linda 56
Tom 55
So I've sorted it but what I need to add a rank column, so it looks like this:
Name Value Rank
Bob 50 1
Todd 50 1
John 51 2
Mary 55 3
Tom 55 3
Linda 56 4
So what I found is:
resultset$Rank <- ave(resultset$Name, resultset$Value, FUN = rank)
But this gives me:
Name Value Rank
Bob 50 1
Todd 50 2
John 51 1
Mary 55 1
Tom 55 2
Linda 56 1
So close but yet so far...
Upvotes: 1
Views: 1155
Reputation: 66819
Here's a base-R solution:
uv <- unique(df$Value)
merge(df,data.frame(uv,r=rank(uv)),by.x="Value",by.y="uv")
which gives
Value Name r
1 50 Bob 1
2 50 Todd 1
3 51 John 2
4 55 Mary 3
5 55 Tom 3
6 56 Linda 4
This is memory inefficient and has the side-effect of resorting your data. You could alternately do:
require(data.table)
DT <- data.table(df)
DT[order(Value),r:=.GRP,by=Value]
which gives
Name Value r
1: Bob 50 1
2: Mary 55 3
3: John 51 2
4: Todd 50 1
5: Linda 56 4
6: Tom 55 3
Upvotes: 2
Reputation: 1417
I guess your rank variable can be obtained by 1:length(unique(df$value))
. Below is my trial.
df <- data.frame(name = c("Bob", "Mary", "John", "Todd", "Linda", "Tom"),
value = c(50, 55, 51, 50, 56, 55))
# rank by lengths of unique values
rank <- data.frame(rank = 1:length(unique(df$value)), value = sort(unique(df$value)))
merge(df, rank, by="value")
value name rank
1 50 Bob 1
2 50 Todd 1
3 51 John 2
4 55 Mary 3
5 55 Tom 3
6 56 Linda 4
Upvotes: 0
Reputation: 193527
No need to sort... You can use dense_rank
from "dplyr":
> library(dplyr)
> mydf %>% mutate(rank = dense_rank(Value))
Name Value rank
1 Bob 50 1
2 Mary 55 3
3 John 51 2
4 Todd 50 1
5 Linda 56 4
6 Tom 55 3
Upvotes: 1