【问题标题】:How to group data, with restrictions on group size in R如何对数据进行分组,并限制 R 中的组大小
【发布时间】:2016-03-08 19:27:32
【问题描述】:

给定一个数据框,我可以对指定属性下的行进行分组,对它们进行计数以了解组的大小,并使用 ID 号对其进行唯一分配。但我真正需要的是执行此过程,以便在以下三个条件下限制组大小:

  1. 如果大小模 3 = 0,则分成所有大小为 3 的较小组,
  2. 如果大小模 3 = 1,则分成大小为 3 的较小组和大小为 2 的两组。
  3. 如果大小模 3 = 2,则分成大小为 3 和大小为 2 的较小组

因此,如果大小为 4,则创建两个组,大小均为 2;而当 size 为 5 时,则分成 size 3 和 2 两组。

我创建了以下最小示例。

这是起始数据。通常,它不会被排序并且可以有更多的列:

   structure(
     list(property = c("A", "B", "B", "C", "C", "C", "D", "D", "D", "D", "E", "E", "E", "E", "E", "F", "F", "F", "F", "F", "F", "G", "G", "G", "G", "G", "G", "G")), 
     class = c("tbl_df", "tbl", "data.frame"), 
     row.names = c(NA, -28L), 
     .Names = "property"
     )

期望的输出是:

structure(
  list(property = c("A", "B", "B", "C", "C", "C", "D", "D", "D", "D", "E", "E", "E", "E", "E", "F", "F", "F", "F", "F", "F", "G", "G", "G", "G", "G", "G", "G"), 
  id = c(1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12)), 
  class = c("tbl_df", "tbl", "data.frame"), 
  row.names = c(NA, -28L), 
  .Names = c("property", "id")
  )

组的顺序并不重要。

【问题讨论】:

    标签: r data-manipulation


    【解决方案1】:

    我首先创建一个函数,该函数将根据您的要求创建相等数量的组。基本上,它总是会创建三个相等数字的组,然后在最后切断那些太多的数字。在特殊情况下,最后一组的长度为 1,最后一个元素被最后一个元素替换,以满足您的条件 2:

    create_grp_idx <- function(x) {
      n <- length(x)
      m <- n %/% 3 + 1
      idx <- rep(1:m, each = 3)[1:n]
      if (n %% 3 == 1 && n > 1) idx[n-1] <- idx[n]
      return (idx)
    }
    

    现在我使用dplyr 将数据按property 分组,然后将create_grp_idx() 应用于每个组,从而创建索引n。然后我使用interaction()property 和新创建的索引n 的每个组合中获取一个因子。由于您在示例中使用数字,因此我将因子转换为数字,最后删除索引为 n 的列。

    library(dplyr)
    group_by(data, property) %>%
      mutate(n = create_grp_idx(property)) %>%
      ungroup %>%
      mutate(id = as.numeric(interaction(property, n))) %>%
      select(-n)
    ## Source: local data frame [28 x 2]
    ## 
    ##    property    id
    ##       (chr) (dbl)
    ## 1         A     1
    ## 2         B     2
    ## 3         B     2
    ## 4         C     3
    ## 5         C     3
    ## 6         C     3
    ## 7         D     4
    ## 8         D     4
    ## 9         D    11
    ## 10        D    11
    ## ..      ...   ...
    

    这并没有完全给出您给出的示例输出,但是由于您说组的顺序无关紧要,我认为这就是您想要的结果。

    【讨论】:

    • 当size modulo 3 = 1时它不起作用,它应该创建两组size 2但它创建size 3组和一组size 1
    • 现在应该更好了。
    • @Stibu 非常感谢。这确实有效。我需要时间来弄清楚它是如何工作的,为此我也感谢你的解释,我会尝试在我的完整数据集上实现它。
    猜你喜欢
    • 1970-01-01
    • 2014-04-13
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多