使用 R 中的多列和组内排名

问题描述 投票:0回答:1

我想使用两个属性对组内的值进行排名。理论上

frank
中的
data.table
应该能够做到这一点,但我遇到了一个障碍,当放入
%>%
语法或在
data.table
语法中拆分成组时,函数不接受两列.

使用

mtcars
数据集,我试图在两个虚拟组中按 cyl 和 disp 进行排序。我可以按照另一篇文章(我无法追踪)中的建议使用
order
对组内的数据进行排序,但我无法设置处理等级关系的方法。我也可以使用
frank
按 cyl 排序然后 disp 但我无法在组内执行该功能。

data(mtcars)

mtcars<-as.data.table(mtcars)%>%select(cyl, disp, gear)
mtcars$gr1<-rep(c("fast", "slow"), 16)
mtcars$gr2<-rep(c("red", "blue"), each=16)

这是我尝试使用但失败的代码,但我不理解错误消息中的提示:

mtcars%>%group_by(gr1, gr2)%>%
  arrange(gr1, gr2, .by.group=TRUE)%>% #by.group to keep within groups : may not be helpful for frank
  mutate(ranks=frank(-cyl, -disp, na.last=TRUE, ties.method="min"))#orders by cyl and then by disp

#Error in `mutate()`:
#  ℹ In argument: `ranks = frank(-cyl, -disp, na.last = TRUE, ties.method = "min")`.
#ℹ In group 1: `gr1 = "fast"`, `gr2 = "blue"`.
#Caused by error in `frankv()`:
#  ! x is a single vector, non-NULL 'cols' doesn't make sense
#Run `rlang::last_error()` to see where the error occurred.

其他试炼

#This method assigns random ranks to ties (same value gets different ranks)

mtcars%>%group_by(gr1, gr2)%>%
  arrange(gr1, gr2, .by.group=TRUE)%>% #by.group is necessary to keep within groups with order
  mutate(ranks=order(order(cyl, disp, decreasing=TRUE)))%>%#orders by cyl and then by disp
  arrange(gr1, gr2, -cyl, -disp, ranks)#to illustrate output

#Ranks by cylinder ONLY 并将相同的排名分配给相同值的关系

mtcars%>%group_by(gr1, gr2)%>%
  arrange(gr1, gr2, .by.group=TRUE)%>% #by.group to keep within groups : may not be helpful for frank
  mutate(ranks=frank(-cyl, na.last=TRUE, ties.method="min"))%>%#orders by cyl and then by disp
  arrange(gr1, gr2, -cyl, -disp, ranks)#to illustrate output

按柱面排名然后disp但不在组内排名

    mtcars$ranks<-mtcars%>%group_by(gr1, gr2)%>%
      arrange(gr1, gr2, .by.group=TRUE)%>% #by.group to keep within groups : may not be helpful for frank
      frank(-cyl, -disp, na.last=TRUE, ties.method="min")
    


#works but only uses cyl
    mtcars[, list(ranks= frank(-cyl,  na.last=TRUE, ties.method="min")), 
                                by=list(gr1, gr2)]
 #fails   
    mtcars[, list(ranks= frank(-cyl, -disp,  na.last=TRUE, ties.method="min")), 
                     by=list(gr1, gr2)]
r data.table rank group mutate
1个回答
1
投票

查看

?frank
帮助页面,当您尝试使用它时,它不接受多个向量作为输入。它接受 (a) 单个向量或 (b) 列表、数据框或 data.table 作为第一个参数,以及列名(或引用列名或索引的向量)。

来自

?frank

争论

x
vector
,或
list
其所有元素的长度相同或
data.frame
data.table
.

...
仅适用于
lists
data.frames
data.tables
。计算排名所依据的列。不要引用列名。如果缺少
...
,默认情况下会考虑所有列。按前缀“
-
”降序排列列,例如,
frank(x, a, -b, c)
-b
b
也是字符类型时也有效。

注意

...
有效 您不想对单个向量进行排名,这意味着您需要使用选项 (b) - 将 data.table 作为其第一个参数,然后指定列。要在 lists 中按组执行此操作,我们使用
data.frames
。 (我不认为这个界面会和
data.tables
玩得很好。)
这是我对您的代码的解释的全部 
frank

版本。你没有提供预期的输出,所以我只能希望这是你想要的。

data.table
感谢 Jamie 的评论,我们可以构建一个 
.SD
 的排名列,我们可以在 
dplyr::group_by
 管道中进行:

data.table

© www.soinside.com 2019 - 2024. All rights reserved.