如何将样本datA的type分组变更同步到总体数据集datB?
如何将样本数据集的分组变更同步到总体数据集?
我有一个样本数据集datA,其中部分组的样本量过小,需要合并这些组。由于后续要基于样本/总体做加权计算,必须把这些分组变更同步到结构相似但行数不同的总体数据集datB,但不能直接对datB应用同样的分组合并代码——因为总体的观测数量足够,不需要合并。
示例数据
library(data.table) datA <- fread(" NA,0,2,NA,cat X, type 1 3,4,3,1,cat X, type 2 1,0,2,2,cat X, type 3 3,4,3,0,cat X, type 4 NA,0,2,NA,cat Y, type 1 NA,4,3,NA,cat Y, type 2 1,0,2,2,cat Y, type 3 3,4,3,35,cat Y, type 4 NA,0,2,NA,cat X, type 1 3,4,3,1,cat X, type 2 1,0,2,2,cat X, type 3 NA,4,3,NA,cat X, type 4 NA,0,2,NA,cat Y, type 1 NA,4,3,NA,cat Y, type 2 1,0,2,2,cat Y, type 3 3,4,3,1,cat Y, type 4 1,0,2,4,cat X, type 1 3,4,3,1,cat X, type 2 1,0,2,2,cat X, type 3 3,4,3,2,cat X, type 4 NA,0,2,NA,cat Y, type 1 NA,4,3,NA,cat Y, type 2 1,0,2,2,cat Y, type 3 3,4,3,2,cat Y, type 4 ") names(datA) <- c("A","B","C", "D", "cat", "type")
对样本数据集datA的分组变更操作
observations_grp <- function(x) { cumsum_i <- 0 nxtgrp <- FALSE n <- length(x) grp <- rep(0,n) grp_i <- 0; for (i in 1:n) { if (nxtgrp) {grp_i <- grp_i + 1; cumsum_i <- 0;} nxtgrp <- !((cumsum_i + x[i]) < 2) cumsum_i <- cumsum_i + x[i] grp[i] <- grp_i } grp } datA <- datA[, observations_D := sum(!is.na(D)), by = c("cat", "type")] datA <- datA[, new_type := type] datA[,`:=`(new_type = last(new_type), observations_D =sum(observations_D)), .(cat,observations_grp(observations_D)) ][]
提取发生分组变更的行:
changed_rows <- datA[type!=new_type]
将变更同步到总体数据集datB
首先创建结构相似的总体数据集datB:
datB <- cbind(datA, datA)
需求说明
需要根据changed_rows中的信息修改datB:当datB的cat和type与changed_rows中的对应值匹配时,将datB的type替换为changed_rows中的new_type。
正确实现代码
你之前尝试的代码会因向量长度不匹配导致错误,正确的做法是先生成唯一的映射规则,再用data.table的连接更新语法完成同步:
- 生成唯一的
cat-type到new_type的映射表(避免重复规则):
type_mapping <- unique(changed_rows[, .(cat, type, new_type)])
- 对
datB执行匹配更新:
setDT(datB)[type_mapping, on = .(cat, type), type := i.new_type]
代码解释
unique()确保每个cat-type组合只保留一条变更规则,避免重复更新。on = .(cat, type)指定匹配条件,将datB与type_mapping中cat和type都相同的行关联。i.new_type表示取type_mapping(连接的右表)中的new_type值,替换datB的type字段。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

