简体   繁体   中英

How to find where a column ranks across a row using dplyr?

Say I have a dataframe that looks like this:

dat <- data.frame(
  Iowa = c(11, 12, 15),
  Wisconsin = c(10, 14, 12),
  Florida = c(14, 9, 11)
)

I want to get the rowwise rank for Iowa relative to the other columns. So the output would look like this:

out <- data.frame(
  Iowa = c(11, 12, 15),
  Wisconsin = c(10, 14, 12),
  Florida = c(14, 9, 11),
  IowaRank = c(2, 2, 1)
)

What's the best way to achieve this using R, ideally in a dplyr pipe?

Easiest will be apply to loop over the rows, apply the rank extract the first row

dat$IowaRank <- apply(-dat, 1, rank)[1,]

-output

dat
  Iowa Wisconsin Florida IowaRank
1   11        10      14        2
2   12        14       9        2
3   15        12      11        1

Or using rowRanks from matrixStats

library(matrixStats)
dat$IowaRank <- rowRanks(-as.matrix(dat))[,1]

Or with dplyr

library(dplyr)
dat %>%
    rowwise %>%
    mutate(IowaRank = rank(-c_across(everything()))[1]) %>%
    ungroup
# A tibble: 3 x 4
   Iowa Wisconsin Florida IowaRank
  <dbl>     <dbl>   <dbl>    <dbl>
1    11        10      14        2
2    12        14       9        2
3    15        12      11        1

You can get the ranks for all the columns using dense_rank -

library(dplyr)
library(tidyr)

dat %>%
  mutate(row = row_number()) %>%
  pivot_longer(cols = -row) %>%
  group_by(row) %>%
  mutate(rank = dense_rank(-value)) %>%
  ungroup %>%
  pivot_wider(names_from = name, values_from = c(value, rank)) %>%
  select(-row)

#  value_Iowa value_Wisconsin value_Florida rank_Iowa rank_Wisconsin rank_Florida
#       <dbl>           <dbl>         <dbl>     <int>          <int>        <int>
#1         11              10            14         2              3            1
#2         12              14             9         2              1            3
#3         15              12            11         1              2            3

If you are interested only in rank of Iowa using rowwise you can do -

dat %>%
  rowwise() %>%
  mutate(IowaRank = dense_rank(-c_across())[1])

#   Iowa Wisconsin Florida IowaRank
#  <dbl>     <dbl>   <dbl>    <int>
#1    11        10      14        2
#2    12        14       9        2
#3    15        12      11        1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM