我有一个数据集,以长格式包含关于个人的重复观测。因此,每行都是类型为A
或B
的观测。以下代码可复制数据集。
library(data.table)
set.seed(1487)
dat <- data.table(id = rep(seq(10), 2),
type = c(rep("A", 10), rep("B", 10)),
x = sample.int(100,20))
dat
# id type x
# 1: 1 A 38
# 2: 2 A 58
# 3: 3 A 28
# 4: 4 A 21
# 5: 5 A 19
# 6: 6 A 62
# 7: 7 A 52
# 8: 8 A 86
# 9: 9 A 85
# 10: 10 A 90
# 11: 1 B 15
# 12: 2 B 11
# 13: 3 B 37
# 14: 4 B 93
# 15: 5 B 34
# 16: 6 B 91
# 17: 7 B 79
# 18: 8 B 94
# 19: 9 B 24
# 20: 10 B 41
然后我选择根据观察类型使用x
排名最高的3个个体:
setorderv(dat, c("type", "x"), c(1, -1))
top3 <- dat[, head(.SD, 3), by = list(type)]
top3
# type id x
# 1: A 10 90
# 2: A 8 86
# 3: A 9 85
# 4: B 8 94
# 5: B 4 93
# 6: B 6 91
现在我想添加一个包含相反观测类型的原始x
值的列。如果有意义的话。因此,以下代码可以复制我正在寻找的内容:
top3[,x2 := c(41, 94, 24, 86, 21, 62)]
# type id x x2
# 1: A 10 90 41
# 2: A 8 86 94
# 3: A 9 85 24
# 4: B 8 94 86
# 5: B 4 93 21
# 6: B 6 91 62
当然,我可以逐行遍历整个数据集并使用if语句或其他方式。原始数据集非常大,我正在寻找一种优雅而高效的方法来完成它。我真的很喜欢data.table,并且最近一直在使用它。我知道有一种简单而优雅的方法来完成它。我还尝试过使用.GRP。我需要一些帮助。
提前感谢!
我的最终解决方案
感谢那些提供灵感的人。对于我的问题,这是我工作中实际运作得更好的解决方案。
dat <- dcast.data.table(dat, id~type, value.var = "x")
top3 <- rbind(dat[order(-A), head(.SD, 3L)][,rank_by := "A"],
dat[order(-B), head(.SD, 3L)][,rank_by := "B"])
# id A B rank_by
# 1: 10 90 41 A
# 2: 8 86 94 A
# 3: 9 85 24 A
# 4: 8 86 94 B
# 5: 4 21 93 B
# 6: 6 62 91 B
Cheers,
tstev