根据两个变量的值进行排名-r
我有这个数据框:根据两个变量的值进行排名-r,r,R,我有这个数据框: df<-data.frame( var1 = c(rep(c(rep(1,2), rep(2,3), rep(3,2), rep(4,1)),2), 1), var2 = c(rep(1,8), rep(2,8),3) ) df var1 var2 #1 1 1 #2 1 1 #3 2 1 #4 2 1 #5 2 1 #6 3 1 #7
df<-data.frame(
var1 = c(rep(c(rep(1,2), rep(2,3), rep(3,2), rep(4,1)),2), 1),
var2 = c(rep(1,8), rep(2,8),3)
)
df
var1 var2
#1 1 1
#2 1 1
#3 2 1
#4 2 1
#5 2 1
#6 3 1
#7 3 1
#8 4 1
#9 1 2
#10 1 2
#11 2 2
#12 2 2
#13 2 2
#14 3 2
#15 3 2
#16 4 2
#17 1 3
这是可行的,但需要对我的df
进行预排序。我想要一个不需要这个的解决方案。我觉得这应该是一个简单的单行程序,使用rank
,我有一个盲点。谢谢你的帮助
编辑1:-添加一个更大的示例以测试建议答案
dput(df1)
df1 <- structure(list(var1 = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L,
3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 7L,
7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 6L, 9L, 10L, 10L, 10L, 11L,
12L, 12L, 12L, 13L, 14L, 14L, 14L, 14L, 15L, 16L, 16L, 16L, 16L,
16L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 19L, 19L,
20L, 20L, 21L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 23L,
24L, 24L, 24L, 24L, 24L, 25L, 25L, 25L, 25L, 25L, 1L, 2L, 2L,
2L, 2L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L,
8L, 9L, 10L, 10L, 10L, 10L, 3L, 11L, 11L, 11L, 11L, 12L, 13L,
13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L,
12L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L,
18L, 18L, 19L, 19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 21L, 22L,
22L, 22L, 23L, 25L, 24L, 24L, 24L, 24L, 24L, 26L, 26L, 26L, 26L,
26L, 27L, 27L, 27L, 27L, 27L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L,
3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L,
6L, 7L, 7L, 7L, 7L, 7L, 8L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L,
11L, 12L, 12L, 13L, 14L, 15L, 16L, 17L, 17L, 18L, 18L, 19L, 19L,
19L, 19L, 20L, 21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 22L, 22L,
23L, 23L, 23L, 23L, 23L, 24L, 24L, 24L, 24L, 24L, 25L, 25L, 25L,
25L, 25L, 26L, 26L, 26L, 27L, 27L, 28L, 28L, 28L, 28L, 28L, 1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L,
4L, 4L, 5L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L), var2 = c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), ranks = c(1L, 1L,
1L, 1L, 1L, 12L, 12L, 12L, 12L, 12L, 19L, 19L, 19L, 19L, 19L,
20L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 23L, 23L, 23L,
23L, 23L, 24L, 24L, 24L, 24L, 24L, 22L, 25L, 2L, 2L, 2L, 3L,
4L, 4L, 4L, 5L, 6L, 6L, 6L, 6L, 7L, 8L, 8L, 8L, 8L, 8L, 9L, 9L,
9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 13L, 13L, 14L,
15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L,
17L, 17L, 18L, 18L, 18L, 18L, 18L, 26L, 37L, 37L, 37L, 37L, 47L,
48L, 48L, 48L, 48L, 49L, 49L, 49L, 49L, 49L, 50L, 50L, 50L, 50L,
51L, 52L, 27L, 27L, 27L, 27L, 46L, 28L, 28L, 28L, 28L, 29L, 30L,
30L, 30L, 30L, 31L, 31L, 31L, 31L, 31L, 32L, 32L, 32L, 32L, 32L,
29L, 33L, 33L, 33L, 33L, 34L, 34L, 34L, 34L, 34L, 35L, 35L, 35L,
35L, 35L, 36L, 36L, 36L, 36L, 36L, 38L, 38L, 38L, 38L, 39L, 40L,
40L, 40L, 41L, 43L, 42L, 42L, 42L, 42L, 42L, 44L, 44L, 44L, 44L,
44L, 45L, 45L, 45L, 45L, 45L, 53L, 64L, 64L, 64L, 64L, 74L, 74L,
74L, 74L, 74L, 75L, 75L, 75L, 75L, 75L, 76L, 76L, 76L, 76L, 76L,
77L, 77L, 77L, 77L, 77L, 78L, 78L, 78L, 78L, 78L, 79L, 80L, 80L,
80L, 80L, 54L, 54L, 54L, 54L, 55L, 56L, 56L, 57L, 58L, 59L, 60L,
61L, 61L, 62L, 62L, 63L, 63L, 63L, 63L, 65L, 66L, 66L, 66L, 66L,
66L, 67L, 67L, 67L, 67L, 67L, 68L, 68L, 68L, 68L, 68L, 69L, 69L,
69L, 69L, 69L, 70L, 70L, 70L, 70L, 70L, 71L, 71L, 71L, 72L, 72L,
73L, 73L, 73L, 73L, 73L, 81L, 81L, 81L, 81L, 81L, 82L, 82L, 82L,
82L, 82L, 83L, 83L, 83L, 83L, 83L, 84L, 84L, 84L, 84L, 85L, 86L,
87L, 87L, 87L, 87L, 88L, 88L, 88L, 88L, 88L)), .Names = c("var1",
"var2", "ranks"), row.names = c(NA, -300L), class = "data.frame")
dput(df1)
df1涉及粘贴[0]
的解决方案只有在每个向量中的值是具有固定位数的整数时才有效。这是因为paste
转换为字符和:
rank(c(1,2,11));排名(如字符(c(1,2,11)))
paste0(2,12);粘贴0(21,2)
order
接受多个排序列,因此如果您不介意如何拆分相同的行order(order(df$var2,df$var1))
执行此任务
这将根据行的原始顺序拆分相同的行。有许多方法可以对相同的行进行排序
2011年,Peter Dalgaard提出了ave(order(order)(df$var2,df$var1)),df$var2,df$var1)
,它给出了维基百科所称的“分数排名”,在base::rank
中是默认的ties.method=“average”
你的例子就是维基百科所称的“密集排名”,它在base::rank
中不可用,但正如David Arenburg所评论的那样,是由dplyr::densed\u rank
提供的,因此你可以库(dyplr)
并使用:
densite_秩(ave(order(order)(df$var2,df$var1)),df$var2,df$var1))
看看稠密等级的代码,它只是
function (x)
{
r <- rank(x)
match(r, sort(unique(r)))
}
您正在按与出现顺序相反的列进行排名,因此
dense_rank(ave(order(do.call(order, rev(df))), df))
或者显式指定列及其顺序
dense_rank(ave(order(do.call(order, df[,2:1])), df[,2:1]))
库(dplyr);密集排列(粘贴(df$var2,df$var1))
?@DavidArenburg这不是要按字典顺序而不是数字顺序排列吗?我认为和(df,dense,rank(var2)+dense,rank(var1)/length(var1))
是有效的,但是必须有一种更简洁的方法来组合var1
和var2
@user20637它将遵循ASCII排序顺序(据我所知),尝试sapply(paste0(df$var2,df$var1)),函数(x)和(strtoi(charToRaw(x),16L))
。同样,如果你想要一个数字顺序,你可以把as.numeric
添加到densite_秩中(as.numeric(paste0(df$var2,df$var1))
@DavidArenburg No。是粘贴
(或paste0
)转换为字符并强制进行字典排序。尝试将作为.numeric(paste0(1.2,3.1))
。有关词典排序顺序,请参见?比较
。最后一个解决方案是密集秩(ave(order(do.call(order,df[,2:1])),df[,2:1])
。非常有用,看看你如何解构这个-谢谢。
dense_rank(ave(order(do.call(order, df)), df))
dense_rank(ave(order(do.call(order, rev(df))), df))
dense_rank(ave(order(do.call(order, df[,2:1])), df[,2:1]))