I have been stuck on a very simple task, reattributing values of a column to another column based on a reversed rank.
Here is my trial with a reproducible example :
df <- data.frame(sum_values = c(1, 20, 11, 30, 5))
df$rk <- rank(df$sum_values) # Calculate ranks based on sum_values
df$rkr <- length(df$rk) + 1 - df$rk # Calculate reversed ranks
df$sum_reversed <- df$sum_values[order(df$rkr)] # attribute reversed sum_values based on reversed rank
When I print the result, I think the attribuation has been made based on the initial order of the observation rather than the reversed rank, and I really don't know how to solve this issue.
You can use match
to get the reversed rank.
df$sum_reversed <- df$sum_values[match(df$rkr, df$rk)]
#df
# sum_values rk rkr sum_reversed
#1 1 1 5 30
#2 20 4 2 5
#3 11 3 3 11
#4 30 5 1 1
#5 5 2 4 20
or using order
.
df$sum_values[order(df$rk)][df$rkr]
#[1] 30 5 11 1 20
Maybe use order
instead of rank
for the case there are two equal values:
rank(c(1,1,2))
#[1] 1.5 1.5 3.0
rank(c(1,1,2), ties.method = "first")
#[1] 1 2 3
order(c(1,1,2))
#[1] 1 2 3
In case there are two equal values the reverse rank need to be estimated different.
Simple sorted data:
DF <- data.frame(x = c(1, 5, 5, 7, 9))
DF$rank <- rank(DF$x)
DF$rx <- rev(DF$x)
DF$rrank <- rank(DF$rx)
DF
# x rank rx rrank
#1 1 1.0 9 5.0
#2 5 2.5 7 4.0
#3 5 2.5 5 2.5
#4 7 4.0 5 2.5
#5 9 5.0 1 1.0
In case it is unsorted.
DF <- data.frame(x = c(1, 7, 5, 9, 5))
DF$rank <- rank(DF$x)
i <- order(DF$x)
DF$rx[i] <- DF$x[rev(i)]
DF$rrank <- rank(DF$rx)
DF
# x rank rx rrank
#1 1 1.0 9 5.0
#2 7 4.0 5 2.5
#3 5 2.5 7 4.0
#4 9 5.0 1 1.0
#5 5 2.5 5 2.5