Reputation: 639
How do you use dplyr
to create ranks for each column based on descending values for multiple columns?
The code below seemingly does not consider the desc
parameter in the arrange_at
rank_f <- function(ds, cols, fs){
ds %>%arrange_at(desc(vars(!!!cols)))%>%
mutate_at(vars(!!!cols), funs(!!!fs))
}
USArrests %>%tibble::rownames_to_column()%>%
rank_f(quos((Murder:Rape)),quos(min_rank))->ranked
head(USArrests)
# Murder Assault UrbanPop Rape
# Alabama 13.2 236 58 21.2
# Alaska 10.0 263 48 44.5
# Arizona 8.1 294 80 31.0
# Arkansas 8.8 190 50 19.5
# California 9.0 276 91 40.6
# Colorado 7.9 204 78 38.7
head(ranked)
# rowname Murder Assault UrbanPop Rape
# 1 Alabama 44 35 16 29
# 2 Alaska 35 43 7 49
# 3 Arizona 29 47 39 43
# 4 Arkansas 31 31 9 24
# 5 California 32 44 50 48
# 6 Colorado 28 33 38 47
The higher the rate, the lower the rank should be, which is not the case.
Upvotes: 4
Views: 2654
Reputation: 887038
We need to place this inside the funs
out1 <- USArrests %>%
tibble::rownames_to_column() %>%
arrange_at(vars(Murder:Rape), funs(desc))
Checking with applying desc
on each column
out2 <- USArrests %>%
tibble::rownames_to_column() %>%
arrange(desc(Murder), desc(Assault), desc(UrbanPop), desc(Rape))
identical(out1, out2)
#[1] TRUE
Based on the above, we can make changes in the rank_f
out3 <- out2 %>%
mutate_at(vars(Murder:Rape), min_rank)
rank_f <- function(ds, cols, fs){
ds %>%
arrange_at(vars(!!!cols), funs(desc))%>%
mutate_at(vars(!!!cols), funs(!!!fs))
}
out4 <- USArrests %>%
tibble::rownames_to_column()%>%
rank_f(quos((Murder:Rape)),quos(min_rank))
identical(out3, out4)
#[1] TRUE
Based on the comments from OP, we don't need to do any arrange
, we can directly apply min_rank
by converting the column values to negative
USArrests %>%
tibble::rownames_to_column() %>%
mutate_at(vars(Murder:Rape), funs(min_rank(-.)))
Upvotes: 2