r - 在 data.table 中对因子级别进行分组

标签 r data.table

我试图在 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 可以加快速度,但与后两种方法相比,它只能将差距减半)

最佳答案

更新:
我最近从 this 学到了一种更简单的方法来重新关联因子水平。问题并仔细阅读 ?levels .不需要合并,对应表等,只需传递一个名为listlevels :

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]

关于r - 在 data.table 中对因子级别进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28181753/

相关文章:

R中的功能区图表

r - Shiny rcharts 多图表输出

r - 与其他数据表相比,评估一个数据表中缺少哪些列变量名称,并自动添加缺少的列

r - 如何在 ggplot2 中添加第二个轴标签?

r - 使用 R 中每个数据帧的相应列名称填充数据帧列表中的列

r - 比较同一数据框中组中的行

r - 如何在for循环中引用变量?

r - 有效地将数据从 data.table 转换为矩阵(速度和内存)

R 数据表 : (dynamic) forward looking Cross-Joins

r - 通过采样连接数据表