我想使用两个属性对组内的值进行排名。理论上
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)]
查看
?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