【问题标题】:Create descending ranks for a set of columns using dplyr使用 dplyr 为一组列创建降序排列
【发布时间】:2018-11-05 06:33:36
【问题描述】:

如何使用dplyr 根据多列的降序值为每一列创建排名? 下面的代码貌似没有考虑arrange_at中的desc参数

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

率越高,排名应该越低,事实并非如此。

【问题讨论】:

  • 目前尚不清楚预期的输出可能是什么。你能显示前几行的预期输出吗

标签: r dplyr


【解决方案1】:

我们需要把它放在funs

out1 <- USArrests %>%
           tibble::rownames_to_column() %>% 
           arrange_at(vars(Murder:Rape), funs(desc)) 

检查并在每列上应用desc

out2 <-  USArrests %>% 
             tibble::rownames_to_column() %>% 
             arrange(desc(Murder), desc(Assault), desc(UrbanPop), desc(Rape))
identical(out1, out2)
#[1] TRUE

基于以上,我们可以对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

更新

基于OP的cmets,我们不需要做任何arrange,我们可以通过将列值转换为负数直接应用min_rank

USArrests %>% 
   tibble::rownames_to_column() %>% 
   mutate_at(vars(Murder:Rape), funs(min_rank(-.)))

【讨论】:

  • 添加%&gt;%arrange(rowname)我还是按升序获得排名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
  • @Lod 请检查identical 输出
  • @Lod 我没有使用quos 并在每一列上分别应用desc 并给出了相同的输出。可能是你的逻辑不清楚
  • 可能是我误解了_at 的工作原理。我正在寻找的是一个新的数据框,其中每一列都有该列的每个观察值的等级。排名基于递减值,因此值越高,排名越低。因此,在我的示例中,阿拉巴马州谋杀案的排名绝对应该低于阿拉斯加州。
  • 是的,这就是我要找的:将 (-.) 放入函数中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
相关资源
最近更新 更多