基于几个变量的排名
Rank based on several variables
这是一个小例子。在我较大的数据集中,我有多年的数据,每组的观察次数 (div) 并不总是相等的。
示例数据:
set.seed(1)
df<-data.frame(
year = 2014,
id = sample(LETTERS[1:26], 12),
div = rep(c("1", "2a", "2b"), each=4),
pts = c(9,7,9,3,7,5,3,7,2,7,7,1),
x = c(10,12,11,7,7,5,4,12,4,6,7,2)
)
df
# year id div pts x
#1 2014 G 1 9 10
#2 2014 J 1 7 12
#3 2014 N 1 9 11
#4 2014 U 1 3 7
#5 2014 E 2a 7 7
#6 2014 S 2a 5 5
#7 2014 W 2a 3 4
#8 2014 M 2a 7 12
#9 2014 L 2b 2 4
#10 2014 B 2b 7 6
#11 2014 D 2b 7 7
#12 2014 C 2b 1 2
我想对这些数据进行排名,使得 div 中 div 1 中的等同者排名高于 div 2a/2b,并且在 div 1 中dividuals 根据 'pts' 的最高数量排名 1、2、3、4,其次是 'x' 的最高数量。
Individuals in div 2a 和 div 2b 也应该根据相同的标准在dividually 中排名。这看起来像这样:
df %>%
group_by(div) %>%
arrange(desc(pts), desc(x)) %>%
mutate(position = row_number(div))
# year id div pts x position
#1 2014 N 1 9 11 1
#2 2014 G 1 9 10 2
#3 2014 J 1 7 12 3
#4 2014 U 1 3 7 4
#5 2014 M 2a 7 12 1
#6 2014 E 2a 7 7 2
#7 2014 S 2a 5 5 3
#8 2014 W 2a 3 4 4
#9 2014 D 2b 7 7 1
#10 2014 B 2b 7 6 2
#11 2014 L 2b 2 4 3
#12 2014 C 2b 1 2 4
但是,我想生成另一个排名的最终 column/variable。这将使 div 1 中的所有 individuals 排名高于 2a/2b,但 2a/2b 是相等的。即在div2a/2b中排名第1的iduals现在应该得到5.5,在dividuals中排名2的现在应该得到7.5。在所有年份中,div2a 和 div2b 中的 individual 总是相等的。
它应该是这样的:
# year id div pts x position final
#1 2014 N 1 9 11 1 1.0
#2 2014 G 1 9 10 2 2.0
#3 2014 J 1 7 12 3 3.0
#4 2014 U 1 3 7 4 4.0
#5 2014 M 2a 7 12 1 5.5
#6 2014 E 2a 7 7 2 7.5
#7 2014 S 2a 5 5 3 9.5
#8 2014 W 2a 3 4 4 11.5
#9 2014 D 2b 7 7 1 5.5
#10 2014 B 2b 7 6 2 7.5
#11 2014 L 2b 2 4 3 9.5
#12 2014 C 2b 1 2 4 11.5
我需要找到一个理想的 dplyr
解决方案。此外,它确实需要推广到 'div1' 中 individuals 的数量可能变化并且 div2a/div2b 中 individuals 的数量变化的年份(尽管长度( div2a)==length(div2b) 总是).
我会这样做:
library(data.table)
dt = as.data.table(df)
dt[order(-pts, -x), rank.init := 1:.N, by = div]
dt[, div.clean := sub('(\d+).*', '\1', div)]
setorder(dt, div.clean, rank.init)
dt[, rank.final := mean(.I), by = .(div.clean, rank.init)]
setorder(dt, div, rank.final)
# year id div pts x rank.init div.clean rank.final
# 1: 2014 N 1 9 11 1 1 1.0
# 2: 2014 G 1 9 10 2 1 2.0
# 3: 2014 J 1 7 12 3 1 3.0
# 4: 2014 U 1 3 7 4 1 4.0
# 5: 2014 M 2a 7 12 1 2 5.5
# 6: 2014 E 2a 7 7 2 2 7.5
# 7: 2014 S 2a 5 5 3 2 9.5
# 8: 2014 W 2a 3 4 4 2 11.5
# 9: 2014 D 2b 7 7 1 2 5.5
#10: 2014 B 2b 7 6 2 2 7.5
#11: 2014 L 2b 2 4 3 2 9.5
#12: 2014 C 2b 1 2 4 2 11.5
@eddi 的回答已经很好了。我只是想使用 data.table, v1.9.5
开发版本中的 frank()
函数来说明相同的情况,它可以计算向量、列表、data.frames 或 data.tables.[=14= 上的排名]
# from @eddi's
setDT(df)[, div.clean := sub('(\d+).*', '\1', div)]
df[, position := frank(.SD, -pts, -x, ties.method="first"), by=div]
df[, final := frank(.SD, div.clean, position, ties.method="average")]
这也保留了原始顺序,如果这很重要的话。
我会把 dplyr
的转换留给你。
这是一个小例子。在我较大的数据集中,我有多年的数据,每组的观察次数 (div) 并不总是相等的。
示例数据:
set.seed(1)
df<-data.frame(
year = 2014,
id = sample(LETTERS[1:26], 12),
div = rep(c("1", "2a", "2b"), each=4),
pts = c(9,7,9,3,7,5,3,7,2,7,7,1),
x = c(10,12,11,7,7,5,4,12,4,6,7,2)
)
df
# year id div pts x
#1 2014 G 1 9 10
#2 2014 J 1 7 12
#3 2014 N 1 9 11
#4 2014 U 1 3 7
#5 2014 E 2a 7 7
#6 2014 S 2a 5 5
#7 2014 W 2a 3 4
#8 2014 M 2a 7 12
#9 2014 L 2b 2 4
#10 2014 B 2b 7 6
#11 2014 D 2b 7 7
#12 2014 C 2b 1 2
我想对这些数据进行排名,使得 div 中 div 1 中的等同者排名高于 div 2a/2b,并且在 div 1 中dividuals 根据 'pts' 的最高数量排名 1、2、3、4,其次是 'x' 的最高数量。
Individuals in div 2a 和 div 2b 也应该根据相同的标准在dividually 中排名。这看起来像这样:
df %>%
group_by(div) %>%
arrange(desc(pts), desc(x)) %>%
mutate(position = row_number(div))
# year id div pts x position
#1 2014 N 1 9 11 1
#2 2014 G 1 9 10 2
#3 2014 J 1 7 12 3
#4 2014 U 1 3 7 4
#5 2014 M 2a 7 12 1
#6 2014 E 2a 7 7 2
#7 2014 S 2a 5 5 3
#8 2014 W 2a 3 4 4
#9 2014 D 2b 7 7 1
#10 2014 B 2b 7 6 2
#11 2014 L 2b 2 4 3
#12 2014 C 2b 1 2 4
但是,我想生成另一个排名的最终 column/variable。这将使 div 1 中的所有 individuals 排名高于 2a/2b,但 2a/2b 是相等的。即在div2a/2b中排名第1的iduals现在应该得到5.5,在dividuals中排名2的现在应该得到7.5。在所有年份中,div2a 和 div2b 中的 individual 总是相等的。
它应该是这样的:
# year id div pts x position final
#1 2014 N 1 9 11 1 1.0
#2 2014 G 1 9 10 2 2.0
#3 2014 J 1 7 12 3 3.0
#4 2014 U 1 3 7 4 4.0
#5 2014 M 2a 7 12 1 5.5
#6 2014 E 2a 7 7 2 7.5
#7 2014 S 2a 5 5 3 9.5
#8 2014 W 2a 3 4 4 11.5
#9 2014 D 2b 7 7 1 5.5
#10 2014 B 2b 7 6 2 7.5
#11 2014 L 2b 2 4 3 9.5
#12 2014 C 2b 1 2 4 11.5
我需要找到一个理想的 dplyr
解决方案。此外,它确实需要推广到 'div1' 中 individuals 的数量可能变化并且 div2a/div2b 中 individuals 的数量变化的年份(尽管长度( div2a)==length(div2b) 总是).
我会这样做:
library(data.table)
dt = as.data.table(df)
dt[order(-pts, -x), rank.init := 1:.N, by = div]
dt[, div.clean := sub('(\d+).*', '\1', div)]
setorder(dt, div.clean, rank.init)
dt[, rank.final := mean(.I), by = .(div.clean, rank.init)]
setorder(dt, div, rank.final)
# year id div pts x rank.init div.clean rank.final
# 1: 2014 N 1 9 11 1 1 1.0
# 2: 2014 G 1 9 10 2 1 2.0
# 3: 2014 J 1 7 12 3 1 3.0
# 4: 2014 U 1 3 7 4 1 4.0
# 5: 2014 M 2a 7 12 1 2 5.5
# 6: 2014 E 2a 7 7 2 2 7.5
# 7: 2014 S 2a 5 5 3 2 9.5
# 8: 2014 W 2a 3 4 4 2 11.5
# 9: 2014 D 2b 7 7 1 2 5.5
#10: 2014 B 2b 7 6 2 2 7.5
#11: 2014 L 2b 2 4 3 2 9.5
#12: 2014 C 2b 1 2 4 2 11.5
@eddi 的回答已经很好了。我只是想使用 data.table, v1.9.5
开发版本中的 frank()
函数来说明相同的情况,它可以计算向量、列表、data.frames 或 data.tables.[=14= 上的排名]
# from @eddi's
setDT(df)[, div.clean := sub('(\d+).*', '\1', div)]
df[, position := frank(.SD, -pts, -x, ties.method="first"), by=div]
df[, final := frank(.SD, div.clean, position, ties.method="average")]
这也保留了原始顺序,如果这很重要的话。
我会把 dplyr
的转换留给你。