这是我最近在R data.table
我有一个索引表,比如DT1。列x将是索引的子集。我将使用这些索引处理更大的rawtable的子表。子表通常会从1到N索引(即y列)
然后例如,我会遇到一个带有原始索引的索引对的表,我想知道相应的新索引。
这就是它的样子
DT1 <- data.table(x=c(0,3,5),y= c(11,22,33))
DT2 <- data.table(x=c(3,3,0,0,5),x=c(0,5,0,3,5))
# > DT1
# x y
# 1: 0 11
# 2: 3 22
# 3: 5 33
# > DT2
# x x
# 1: 3 0
# 2: 3 5
# 3: 0 0
# 4: 0 3
# 5: 5 5
这是我发现的一种曲折的方式
cbind(DT1[DT2[,1,with=FALSE],on="x"][,2,with=FALSE],DT1[DT2[,2,with=FALSE],on="x"][,2,with=FALSE])
# y y
# 1: 22 11
# 2: 22 33
# 3: 11 11
# 4: 11 22
# 5: 33 33
使用sapply
执行此操作的更基本方法会产生相同的结果
tab=DT1$x
lookup <- function(value){DT1$y[which(tab==value)]}
colnames(DT2) <- c("x","xx")
ans <- as.data.table(cbind(sapply(DT2$x,lookup),sapply(DT2$xx,lookup)))
colnames(ans) <- c("y","y")
然而, 第一个解决方案对我来说有点难看
我不喜欢第二个,因为每次我在lapply
中使用函数查找时,我都需要为tab定义一个值。
如果我必须在不同的表中查找,我可以选择创建特定于该表的新查找函数,或者在(temp)变量选项卡中存储在内存中。
也许有一种方法可以使用两个变量的函数来执行lapply
lookup <-function (tab,value) {...}
?我不知道
我确定还有很多其他方法。
我不确定我对第一个解决方案做了什么。基本上data.table
中的语法与(内部和外部)JOINS有关。但在最终输出中,我想保持表DT2的原始顺序。将列x设置为DT2的键会对该列进行排序,使merge
之类的东西不适应那个?
我愿意听取您的最佳实施方案, - 我确信有更好的实施方案 - 而且,在处理非常大的桌子时效率最高。
答案 0 :(得分:7)
惯用的 data.table 方法是在加入时更新 DT2
,如下所示:
require(data.table) # v1.9.6
setnames(DT2, c("a", "b")) # no duplicate names!!
for (nm in names(DT2)) {
DT2[DT1, paste0(nm, ".val") := y, on = structure("x", names=nm)]
}
DT2[]
# a b a.val b.val
# 1: 3 0 22 11
# 2: 3 5 22 33
# 3: 0 0 11 11
# 4: 0 3 11 22
# 5: 5 5 33 33
您可以使用lapply()
隐藏循环。如果DT2
代替如下(长格式,请参阅DT3
):
DT3 = melt(DT2, measure = c("a", "b"), variable.name = "id", value.name = "x.val")
然后你可以这样做:
DT3[DT1, y.val := y, on = c(x.val = "x")]
您可以使用y.val := i.y
更明确地指出您对应于y
参数的data.table中的i
列。(当它们两者都有用时有共同的列名。)
答案 1 :(得分:1)
您可以尝试以下内容:
@teachers = Teacher.where.not(user_id: nil).order(created_at: :desc)