我正在尝试将data.table
&想知道是否有data.table
- y的方法。
示例:
DT = data.table(id = 1:20, ind = as.factor(sample(8, 20, replace = TRUE)))
我想说类型1,3,8属于A组; 2和4属于B组;和5,6,7属于C组。
以下是我一直在做的事情,这个问题的完整版本速度很慢:
DT[ind %in% c(1, 3, 8), grp := as.factor("A")]
DT[ind %in% c(2, 4), grp := as.factor("B")]
DT[ind %in% c(5, 6, 7), grp := as.factor("C")]
this相关问题建议的另一种方法,我猜这样翻译:
DT[ , grp := ind]
levels(DT$grp) = c("A", "B", "A", "B", "C", "C", "C", "A")
或者或许(考虑到我有65个基础组和18个聚合组,这感觉有点整洁)
DT[ , grp := ind]
lev <- letters(1:8)
lev[c(1, 3, 8)] <- "A"
lev[c(2, 4)] <- "B"
lev[5:7] <- "C"
levels(DT$grp) <- lev
这两个看起来都很笨拙;这似乎是在data.table
中执行此操作的合适方法吗?
作为参考,我用10,000,000个观测值和一些更多的子组/超级组等级来加强了这个版本。我最初的方法是最慢的(必须运行所有那些逻辑检查是昂贵的),第二个是最快的,第三个是接近的第二个。但我更喜欢这种方法的可读性。
(在搜索前加密DT
可以加快速度,但与后两种方法的差距只有一半)
答案 0 :(得分:6)
我最近了解了一种更简单的方法,可以将this问题中的因子水平重新关联起来,并仔细阅读?levels
。不需要合并,对应表等,只需将名为list
的{{1}}传递给levels
:
levels(DT$ind) = list(A = c(1, 3, 8), B = c(2, 4), C = 5:7)
根据@Arun的建议,我们可以选择将对应关系创建为单独的data.table
,然后将其加入原始对象:
match_dt = data.table(ind = as.factor(1:12),
grp = as.factor(c("A", "B", "A", "B", "C", "C",
"C", "A", "D", "E", "F", "D")))
setkey(DT, ind)
setkey(match_dt, ind)
DT = match_dt[DT]
我们也可以这样做(我认为是这样)更具可读性(如边际速度成本):
levels <- letters[1:12]
levels[c(1, 3, 8)] <- "A"
levels[c(2, 4)] <- "B"
levels[5:7] <- "C"
levels[c(9, 12)] <- "D"
levels[10] <- "E"
levels[11] <- "F"
match_dt <- data.table(ind = as.factor(1:12),
grp = as.factor(levels))
setkey(DT, ind)
setkey(match_dt, ind)
DT = match_dt[DT]