当前位置: 首页 > 知识库问答 >
问题:

按预定义的最大组和对数值向量进行分组

龙永逸
2023-03-14

我有一个这样的数值向量x

data.frame(x= c(1, 23,  7,  10,  9,  2,  4), group= c(1, 1, 2, 2, 3, 3, 3))

我用cumsum尝试了不同的方法,但一旦达到最后一组25的限制和,我就无法为新组动态重启cumsum。


共有3个答案

危飞跃
2023-03-14

在base R中,还可以使用Reduce

do.call(rbind, Reduce(\(x,y) if((z<-x[1] + y) > 25) c(y, x[2]+1)
       else c(z, x[2]), x[-1], init = c(x[1], 1), accumulate = TRUE))

     [,1] [,2]
[1,]    1    1
[2,]   24    1
[3,]    7    2
[4,]   17    2
[5,]    9    3
[6,]   11    3
[7,]   15    3

分解:

f <- function(x, y){
  z <- x[1] + y
  if(z > 25) c(y, x[2] + 1)
  else c(z, x[2])
}

do.call(rbind, Reduce(f, x[-1], init = c(x[1], 1), accumulate = TRUE))

如果使用累积

library(tidyverse)
accumulate(x[-1], f, .init = c(x[1], 1)) %>%
invoke(rbind, .)

     [,1] [,2]
[1,]    1    1
[2,]   24    1
[3,]    7    2
[4,]   17    2
[5,]    9    3
[6,]   11    3
[7,]   15    3
公羊安怡
2023-03-14

我认为cpp功能是最快的方式:

library(Rcpp)
cppFunction(
    "IntegerVector GroupBySum(const NumericVector& x, const double& max_sum = 25)
    {
        double sum = 0;
        int cnt = 0;
        int period = 1;
        IntegerVector res(x.size());
        for (int i = 0; i < x.size(); ++i)
        {
            ++cnt;
            sum += x[i];
            if (sum > max_sum)
            {
                sum = x[i];
                if (cnt > 1)
                    ++period;
                cnt = 1;
            }
            res[i] = period;
        }
        return res;
    }"
)
GroupBySum(c(1, 23,  7,  10,  9,  2,  4), 25)
戎劲
2023-03-14

您可以使用MESS包中的累积绑定内置函数:

# install.packages("MESS")
MESS::cumsumbinning(x, 25, cutwhenpassed = F)
# [1] 1 1 2 2 3 3 3

也可以使用purr::acculate

cumsum(x == accumulate(x, ~ifelse(.x + .y <= 25, .x + .y, .y)))
# [1] 1 1 2 2 3 3 3
group <- MESS::cumsumbinning(x, 25, cutwhenpassed = F)
data.frame(x= c(1, 23,  7,  10,  9,  2,  4), 
           group = group)

   x group
1  1     1
2 23     1
3  7     2
4 10     2
5  9     3
6  2     3
7  4     3

快速基准:

x<- c(1, 23,  7,  10,  9,  2,  4)
bm <- microbenchmark(
  fThomas(x),
  fJKupzig(x), 
  fCumsumbinning(x), 
  fAccumulate(x),
  fReduce(x),
  fRcpp(x),
  times = 100L,
  setup = gc(FALSE)
)
autoplot(bm)
x = runif(100, 1, 50)
 类似资料:
  • 问题内容: 带有以下数据 我想产生以下输出: 如果我按价格分组并显示最大日期和最小日期,那么我将得到以下不是我想要的内容(请参见重叠的日期)。 因此,基本上我想做的是根据组列产品和价格对数据进行逐步更改。 什么是最干净的方法来做到这一点? 问题答案: 有一种(或多或少)解决此类问题的已知技术,涉及两个调用,如下所示: 输出:

  • 问题内容: 我有一个多维数组,正在尝试根据特定列中的值将它们分组。 我正在尝试按分组,但实际上我不会事先知道该等级。因此,并不是像我可以将其放在循环中然后说那样,因为我不知道这是级别键的最大值,并且坦率地说,即使我我不确定这也不是我需要这样做的方式。做了… 我希望产生的是: 问题答案: 你需要将它们按 级别 第一 使用 foreach 循环进入数组,检查级别是否与上一个项目相同,然后将其与该数组分

  • 问题内容: 我需要按Field1的值对所有记录进行分组,并为每个组计算Field2的最大值。因此,有什么方法可以使最大聚合作用在同一查询中的多个组上? 问题答案:

  • 我有一个类似[101、107、106、199、204、205、207、306、310、312、312、314、317、318、380、377、379、382、466、469、471、472、557、559、562、566、569…] 在这个数组中,在几个整数之后,值将发生阶跃变化。(如[101107106]和[199204,…])或者换句话说,数组由整数组组成,每组的值以未知均值为中心。但我不知道

  • 问题内容: 我有一个数组数组: 需要按特定顺序进行: 3452342 5867867 7867867 1231233 我将如何去做?我之前已经对数组进行了排序,并阅读了许多其他文章,但它们始终基于比较(即valueA <valueB)。 感谢帮助。 问题答案: 您可以用来精确指示如何对数组进行排序。在这种情况下,可以在比较函数中使用该数组。 下面的示例使用a 使生活更轻松。 这项工作的关键是使要比

  • 我想用多个变量分组,用数字求和,用java中的list得到结果。与SQL group by一样,我希望将数据记录与最低的字符串合并。我想做的与下面的SQL相同, 如果数据存在于下面的项目表中, 我预计结果会在下面。当用orderId按00-82-947和00-82-952分组时,我想像SQL分组一样得到较低的一个。 如何在Java中实现这一点?我认为这对我来说是可行的,但在这种情况下,未按分组的o