我有一个数据集,包含一个长格式的个人重复观察.所以每一行作为一种类型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
Run Code Online (Sandbox Code Playgroud)
然后我选出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
Run Code Online (Sandbox Code Playgroud)
现在我想添加一个包含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
Run Code Online (Sandbox Code Playgroud)
当然,我可以逐行浏览整个数据集并使用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
Run Code Online (Sandbox Code Playgroud)
干杯,
tstev
好像你想要合并回来id和相反的类型.根据您的具体情况,我可能只是跳过更改类型,并在两种类型上合并,并丢弃相同的类型(以下代码假定版本1.9.5+):
(dat[order(-x), head(.SD, 3), by = type]
[dat, on = 'id', nomatch = 0][type != i.type]
[order(type, -id)])
# type id x i.type i.x
#1: A 10 90 B 41
#2: A 8 86 B 94
#3: A 9 85 B 24
#4: B 8 94 A 86
#5: B 4 93 A 21
#6: B 6 91 A 62
Run Code Online (Sandbox Code Playgroud)