使用data.table在R中查找

tst*_*tev 4 r data.table

我有一个数据集,包含一个长格式的个人重复观察.所以每一行作为一种类型AB观察.以下代码重现数据集.

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

edd*_*ddi 6

好像你想要合并回来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)

  • @jangorecki检查编辑 - 我正在尝试格式化,我认为我更喜欢这个 - 似乎更具可读性,并且被分成逻辑部分(以额外括号为代价) (2认同)