使用dplyr为一组列创建降序排名

4

如何使用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

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

不清楚预期输出是什么。你能展示前几行的预期输出吗? - akrun
1个回答

2
我们需要把这个放在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的评论,我们不需要进行任何arrange操作,我们可以直接通过将列值转换为负数来应用min_rank

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

使用 %>%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
@Lod 请检查“identical”输出。 - akrun
@Lod 我展示了两种方法,一种是不使用 quos,另一种是分别在每个列上应用 desc,它们都给出了相同的输出结果。也许你的逻辑不清楚。 - akrun
1
是的,这就是我要找的:将 (-.) 传递到函数中。 - Lod
你有什么建议? - Lod
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接