用 data.table 在 R 中重建索引?
Reindexing in R with data.table?
这是我最近在 R 中遇到的一个常见问题 data.table
我有一个索引 table,比如 DT1。列 x 将是索引的子集。我将使用这些索引处理更大的 rawtable 的 subtable。 subtable 通常会从 1 到 N 进行索引。(即 y 列)
然后例如,我会遇到一个 table 与原始索引成对的索引,我想知道相应的新索引。
这是它的样子
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
中的函数查找时定义一个值给选项卡。
如果我必须在不同的 table 中查找,我可以选择创建一个特定于 table 的新查找函数,或者将其存储在内存中的(临时)变量选项卡中。
也许有一种方法可以用两个变量的函数来做 lapply
lookup <-function (tab,value) {...}
?我不知道
我相信还有很多其他方法。
我不确定第一个解决方案到底在做什么。基本上 data.table
中的语法与(内部和外部)JOINS 有关。但在最终输出中,我想保留 table DT2 的原始顺序。将列 x 设置为 DT2 的键将对该列进行排序,使 merge
之类的内容不适应该列?
我很乐意听取您的意见,什么是最好的实现,我相信还有很多更好的实现,而且,在处理非常非常大的 table 时效率最高。
您可以尝试以下操作:
DT2[, lapply(.SD, function(x) DT1[["y"]][match(x, DT1[["x"]])])]
# x x
# 1: 22 11
# 2: 22 33
# 3: 11 11
# 4: 11 22
# 5: 33 33
str(.Last.value)
# Classes ‘data.table’ and 'data.frame': 5 obs. of 2 variables:
# $ x: num 22 22 11 11 33
# $ x: num 11 33 11 22 33
# - attr(*, ".internal.selfref")=<externalptr>
惯用的 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
更明确地表示您指的是 data.table 中对应于 i
参数的 y
列..(当它们都有共同的列名)。
这是我最近在 R 中遇到的一个常见问题 data.table
我有一个索引 table,比如 DT1。列 x 将是索引的子集。我将使用这些索引处理更大的 rawtable 的 subtable。 subtable 通常会从 1 到 N 进行索引。(即 y 列)
然后例如,我会遇到一个 table 与原始索引成对的索引,我想知道相应的新索引。
这是它的样子
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
中的函数查找时定义一个值给选项卡。
如果我必须在不同的 table 中查找,我可以选择创建一个特定于 table 的新查找函数,或者将其存储在内存中的(临时)变量选项卡中。
也许有一种方法可以用两个变量的函数来做 lapply
lookup <-function (tab,value) {...}
?我不知道
我相信还有很多其他方法。
我不确定第一个解决方案到底在做什么。基本上 data.table
中的语法与(内部和外部)JOINS 有关。但在最终输出中,我想保留 table DT2 的原始顺序。将列 x 设置为 DT2 的键将对该列进行排序,使 merge
之类的内容不适应该列?
我很乐意听取您的意见,什么是最好的实现,我相信还有很多更好的实现,而且,在处理非常非常大的 table 时效率最高。
您可以尝试以下操作:
DT2[, lapply(.SD, function(x) DT1[["y"]][match(x, DT1[["x"]])])]
# x x
# 1: 22 11
# 2: 22 33
# 3: 11 11
# 4: 11 22
# 5: 33 33
str(.Last.value)
# Classes ‘data.table’ and 'data.frame': 5 obs. of 2 variables:
# $ x: num 22 22 11 11 33
# $ x: num 11 33 11 22 33
# - attr(*, ".internal.selfref")=<externalptr>
惯用的 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
更明确地表示您指的是 data.table 中对应于 i
参数的 y
列..(当它们都有共同的列名)。