是否有 R 函数或 SQL 解决方案用于将所有相同的数字重复分组并将它们分配给所有行?

Posted

技术标签:

【中文标题】是否有 R 函数或 SQL 解决方案用于将所有相同的数字重复分组并将它们分配给所有行?【英文标题】:Is there an R function or SQL solution for grouping the all the same numbers repeatedly in a row and assign them to all rows?? 【发布时间】:2019-07-12 09:36:22 【问题描述】:

我想将序列中的连续数字组合成一对。最终目标是计算每组的对数。

我尝试通过在 Redshift 中结合使用 row_number、lag 和 lead 来解决这个问题。

** 我不关心递减区间,但我只想在递增部分建群。

我的桌子

id  number 
ㅡㅡㅡㅡ
a  | 0 
a  | 0 
a  | 1 
a  | 2 
a  | 3 
a  | 2 
a  | 1 
a  | 2 
a  | 1

预期

id  number group 
ㅡㅡㅡㅡㅡㅡㅡㅡㅡ
a  | 0   |  0
a  | 0   |  0
a  | 1   |  3
a  | 2   |  3
a  | 3   |  3
a  | 2   |  0
a  | 1   |  2
a  | 2   |  2
a  | 1   |  0

决赛桌

group cnt
---------
 2  |  2
 3  |  3

提前致谢!

【问题讨论】:

我不明白预期的输出。组总是重要的吗?同样,对于组 2,为什么 1 得到一个分组?对于第 3 组,从 0 到 1 不会更改组列。那么为什么从 2 变为 1 会将组更改为“2”? @Cole 嗨,科尔,我想要的不是担心减少数量,而是只考虑增加的数量。此外,目标是根据增加部分中连续增加的次数对相同的数字进行分组。 SQL 解决方案需要第三个变量来指定行顺序。为什么四个连续的行 a0,a1,a2,a3 在一个值为 4 的组中(这会违反“仅在增加部分构建组”吗?或者相反,为什么 a1,a2 是一个组 = 2(不t 这违反了“仅在增加的部分中构建组”),而不是仅在组中的 a2 = 1 【参考方案1】:

我的解决方案(有意将所有步骤留在预期的数据框中):

library(dplyr)

df<-tibble(id = "a", number = c(0,0,1,2,3,1,2,1))
expected <- df %>% 
    mutate(l = lag(number), 
           l = if_else(is.na(l), 0, l), 
           splits = l < number & l > 0, #remove & l > 0 if starting from 0 is allowed, change to l + 1 == number if step must be 1
           g = cumsum(!splits)) %>% 
    group_by(g) %>% 
    mutate(group = n()) %>% 
    ungroup()

final <- expected %>% 
    filter(group != 1) %>% 
    group_by(group) %>% 
    summarise(cnt = n())

无论如何,group 和 cnt 的值在决赛桌中总是相同的,所以你可以使用 unique()。所以我不确定这是否是你所期望的

【讨论】:

这是我想要的解决方案。非常感谢您的帮助。【参考方案2】:

你可以用一个 for 循环的方式来解决这个问题,它可以识别 min 的序列。 2 值,并为组变量分配序列中出现的最后一个数字的值。结果可以是提供组变量的原始数据集或聚合

X <- data.frame(number = c(0L,0L,1L,2L,3L,2L,1L,2L,1L))

aggrIt <- function(DF = X, raw = T)
  g <- 1L
  result <- rep(0L, nrow(DF))
  for(i in seq_len(nrow(DF)))
    if(i == nrow(DF)) break
    if(i == 1L) 
      if(DF$number[i] != 0L && DF$number[i+1L] == DF$number[i] + 1L) result[i] <- g
      if(DF$number[i] != 0L && DF$number[i+1L] != DF$number[i] + 1L) result[i] <- 0L
                 else 
        if(DF$number[i] != 0L && DF$number[i+1L] == DF$number[i] + 1L) 
          result[i] <- g 
           else 
              if(DF$number[i-1L] == DF$number[i] - 1L) 
                                                    result[i] <- g
                                                    g <- g + 1L
                                                      
                  
      
  

  transl <- tapply(DF$number[result != 0L], result[result != 0L], function(i) rep(max(i), length(i)), simplify = F)
  DF$group <- 0L
  DF$group[result %in% names(transl)] <- unlist(transl)
  if(raw) return(DF)
  return(setNames(aggregate(number~group, DF, length, subset = group != 0L), c("group", "cnt")))

aggrIt(X, raw= F)
  #group cnt
#1     2   2
#2     3   3
aggrIt(X, raw = T)
  #number group
#1      0     0
#2      0     0
#3      1     3
#4      2     3
#5      3     3
#6      2     0
#7      1     2
#8      2     2
#9      1     0

您可以将该功能应用于 id 组。

【讨论】:

感谢您的回答。这也是一个很好的解决方案。但是,我需要慢慢看才能理解整个逻辑。再次感谢您!

以上是关于是否有 R 函数或 SQL 解决方案用于将所有相同的数字重复分组并将它们分配给所有行?的主要内容,如果未能解决你的问题,请参考以下文章

在tapply或R中使用近似函数

是否有像* interface *这样的概念用于函数?

是否有任何包或方法可以将 data.table R 代码转换/发送为 sql 查询以发送到数据库?

是否有列出 SQL Server 中所有内置函数的系统表或系统视图?

是否有用于对数据帧的每一列执行基本操作的 R 函数? [复制]

R语言ggplot2可视化多因子分组条形图使用position_dodge2函数配置所有的条形宽度相同不管分组是否只有一个因子