如何实现不受数据顺序影响的自动分组函数,或恢复原数据排序
问题:数据顺序影响分组函数运行,求解决方案
背景
此前在Stack Overflow提出过相关分组问题,但数据场景复杂时原有方案失效。为此构建四类测试场景验证问题:
- sample_dat:新增
by组类别 - sample_dat2:行随机排序
- sample_dat3:随机删除部分行
- sample_dat4:随机重复部分行
测试结论
仅数据顺序会导致原有方案出错(删除行无影响,重复行出现与sample_dat2相同的问题)。
排序尝试失败
尝试通过sample_dat2_to1 <- sample_dat2[order(cat, year, type),]将sample_dat2还原为sample_dat的排序,但未达到预期,输出示例:
A B C D cat type observations year 1: 1 0 2 NA cat X type 1 1 2010 2: 1 0 2 NA cat X type 1 1 2010 3: 1 0 2 4 cat X type 1 1 2010 4: 3 4 3 1 cat X type 2 3 2010 5: 3 4 3 1 cat X type 2 3 2010 6: 3 4 3 1 cat X type 2 3 2010 7: 1 0 2 2 cat X type 3 3 2010 8: 1 0 2 2 cat X type 3 3 2010
核心诉求
如何将sample_dat2还原为sample_dat的排序以适配原有函数,或修改Waldi与ThomasIsCoding编写的observations_grp函数,使其独立于数据顺序?
测试数据与代码
sample_dat <- structure(list(A = c(1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3), B = c(0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4), C = c(2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3), D = c(NA, 1, 2, 0, NA, NA, 2, 35, NA, 1, 2, NA, NA, NA, 2, 1, 4, 1, 2, 2, NA, NA, 2, 2, NA, 1, 2, 0, NA, NA, 2, 35, NA, 1, 2, NA, NA, NA, 2, 1, 4, 1, 2, 2, NA, NA, 2, 2), cat = c("cat X", "cat X", "cat X", "cat X", "cat Y", "cat Y", "cat Y", "cat Y", "cat X", "cat X", "cat X", "cat X", "cat Y", "cat Y", "cat Y", "cat Y", "cat X", "cat X", "cat X", "cat X", "cat Y", "cat Y", "cat Y", "cat Y", "cat X", "cat X", "cat X", "cat X", "cat Y", "cat Y", "cat Y", "cat Y", "cat X", "cat X", "cat X", "cat X", "cat Y", "cat Y", "cat Y", "cat Y", "cat X", "cat X", "cat X", "cat X", "cat Y", "cat Y", "cat Y", "cat Y"), type = c("type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4", "type 1", "type 2", "type 3", "type 4"), observations = c(1, 3, 3, 2, 0, 0, 3, 3, 1, 3, 3, 2, 0, 0, 3, 3, 1, 3, 3, 2, 0, 0, 3, 3, 1, 3, 3, 2, 0, 0, 3, 3, 1, 3, 3, 2, 0, 0, 3, 3, 1, 3, 3, 2, 0, 0, 3, 3), year = c(2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -48L)) sample_dat <- data.table(sample_dat) set.seed(1) sample_dat2 <- sample_dat[sample(nrow(sample_dat)),] # row_nums <- floor(runif(10, min=1, max=48)) row_nums <- c(43, 14, 22, 16, 31, 13, 23, 37, 4, 42) sample_dat3 <- sample_dat[-row_nums] sample_dat4 <- rbind(sample_dat, sample_dat[row_nums]) observations_grp <- function(x) { cumsum_i <- 0 nxtgrp <- F 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 } sample_dat[,`:=`(type = last(type), observations=sum(observations)), .(cat, year ,observations_grp(observations)) ][] sample_dat2[,`:=`(type = last(type), observations=sum(observations)), .(cat, year ,observations_grp(observations)) ][] sample_dat3[,`:=`(type = last(type), observations=sum(observations)), .(cat, year ,observations_grp(observations)) ][] sample_dat4[,`:=`(type = last(type), observations=sum(observations)), .(cat, year ,observations_grp(observations)) ][]
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

