是否使用data.table在R中重新编制索引?
这是我最近在R中遇到的一个关于是否使用data.table在R中重新编制索引?,r,indexing,data.table,lookup,lapply,R,Indexing,Data.table,Lookup,Lapply,这是我最近在R中遇到的一个关于数据的常见问题。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
数据的常见问题。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
使用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")
tab=DT1$x
查找您可以尝试以下方法:
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>
DT2[,lapply(.SD,函数(x)DT1[[“y”]][匹配(x,DT1[[“x”]])]
#x x
# 1: 22 11
# 2: 22 33
# 3: 11 11
# 4: 11 22
# 5: 33 33
str(.Last.value)
#类“data.table”和“data.frame”:5个obs。共有2个变量:
#$x:num 22 11 11 33
#$x:num 11 33 11 22 33
#-attr(*,“.internal.selfref”)=
惯用的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
也许可以使用lappy()
隐藏循环。如果DT2
改为如下(格式较长;请参见DT3
):
然后你可以做:
DT3[DT1, y.val := y, on = c(x.val = "x")]
您可以使用y.val:=i.y
更明确地说明您是在引用与i
参数对应的data.table中的y
列。。(当它们都有共同的列名时非常有用)。DT2[,lapply(.SD,函数(x)因子(x,levels=DT1$x,labels=DT1$y))]
太好了,谢谢!.SD是什么意思?@AnandaMahto-代码非常简洁,尽管它在部分使用data.frame
语法。不过,我不确定有什么好办法。@LateMail,您是指使用$
?@fagui窗帘,来自?数据。table
:.SD是一个data.table,包含每个组的x数据子集,不包括by(或keyby)中使用的任何列。由于我们没有指定任何“by”,因此,.SD
在这里适用于所有列。有没有办法避免for循环?而不是像您的DT2
结构那样。for循环有什么问题?编辑以显示DT2
应该如何使用一个连接。谢谢大家,有很多有用的答案。。。。实际上现在有这么多答案,我不知道在实践中选择哪一个。。。
DT3 = melt(DT2, measure = c("a", "b"), variable.name = "id", value.name = "x.val")
DT3[DT1, y.val := y, on = c(x.val = "x")]