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

按组和总和创建组合

樊博雅
2023-03-14

我在ID号中包含姓名数据以及许多关联值。它看起来像这样:

structure(list(id = c("a", "a", "b", "b"), name = c("bob", "jane", 
"mark", "brittney"), number = c(1L, 2L, 1L, 2L), value = c(1L, 
2L, 1L, 2L)), class = "data.frame", row.names = c(NA, -4L))

#   id     name number value
# 1  a      bob      1     1
# 2  a     jane      2     2
# 3  b     mark      1     1
# 4  b brittney      2     2

我想创建名称的所有组合,不管有多少个,并将它们粘贴在一起,用逗号分隔,并在每个id中求其编号和值的总和。上述示例的预期输出为:

structure(list(id = c("a", "a", "a", "b", "b", "b"), name = c("bob", 
"jane", "bob, jane", "mark", "brittney", "mark, brittney"), number = c(1L, 
2L, 3L, 1L, 2L, 3L), value = c(1L, 2L, 3L, 1L, 2L, 3L)), class = "data.frame", row.names = c(NA, -6L))

#   id           name number value
# 1  a            bob      1     1
# 2  a           jane      2     2
# 3  a      bob, jane      3     3
# 4  b           mark      1     1
# 5  b       brittney      2     2
# 6  b mark, brittney      3     3

谢谢大家!

共有3个答案

班昱
2023-03-14

A<代码>数据。表选项

setDT(df)[
  ,
  lapply(
    .SD,
    function(x) {
      unlist(
        lapply(
          seq_along(x),
          combn,
          x = x,
          function(v) {
            ifelse(all(is.character(v)), toString, sum)(v)
          }
        )
      )
    }
  ),
  id
]

给予

   id           name number value
1:  a            bob      1     1
2:  a           jane      2     2
3:  a      bob, jane      3     3
4:  b           mark      1     1
5:  b       brittney      2     2
6:  b mark, brittney      3     3
向修谨
2023-03-14

您可以使用combn()创建成对索引,并使用slice()扩展数据帧。然后根据这些行对分组并总结。我假设你想要成对组合,但如果需要的话,这可以适用于更大的集合。一些处理组的代码

library(dplyr)
library(purrr)

df1 %>%
  group_by(id) %>%
  slice(c(combn(seq(n()), min(n(), 2)))) %>%
  mutate(id2 = (row_number()-1) %/% 2) %>%
  group_by(id, id2) %>%
  summarise(name = toString(name),
            across(where(is.numeric), sum), .groups = "drop") %>%
  select(-id2) %>%
  bind_rows(df1 %>%
              group_by(id) %>%
              filter(n() > 1), .) %>%
  arrange(id) %>%
  ungroup()

# A tibble: 6 × 4
  id    name           number value
  <chr> <chr>           <int> <int>
1 a     bob                 1     1
2 a     jane                2     2
3 a     bob, jane           3     3
4 b     mark                1     1
5 b     brittney            2     2
6 b     mark, brittney      3     3

编辑:

为了适应所有可能的组合,您可以遍历最大组大小的值。使用已编辑的数据,其中有几行添加到第一组:

map_df(seq(max(table(df2$id))), ~
         df2 %>%
         group_by(id) %>%
         slice(c(combn(seq(n()), .x * (.x <= n())))) %>%
         mutate(id2 = (row_number() - 1) %/% .x) %>%
         group_by(id, id2) %>%
         summarise(name = toString(name),
                   across(where(is.numeric), sum), .groups = "drop")
       ) %>%
  select(-id2) %>%
  arrange(id)

# A tibble: 18 × 4
   id    name                      number value
   <chr> <chr>                      <int> <int>
 1 a     bob                            1     1
 2 a     jane                           2     2
 3 a     sophie                         1     1
 4 a     jeremy                         2     2
 5 a     bob, jane                      3     3
 6 a     bob, sophie                    2     2
 7 a     bob, jeremy                    3     3
 8 a     jane, sophie                   3     3
 9 a     jane, jeremy                   4     4
10 a     sophie, jeremy                 3     3
11 a     bob, jane, sophie              4     4
12 a     bob, jane, jeremy              5     5
13 a     bob, sophie, jeremy            4     4
14 a     jane, sophie, jeremy           5     5
15 a     bob, jane, sophie, jeremy      6     6
16 b     mark                           3     5
17 b     brittney                       4     6
18 b     mark, brittney                 7    11

df2的数据:

df2 <- structure(list(id = c("a", "a", "a", "a", "b", "b"), name = c("bob", 
                                                                     "jane", "sophie", "jeremy", "mark", "brittney"), number = c(1L, 
                                                                                                                                 2L, 1L, 2L, 3L, 4L), value = c(1L, 2L, 1L, 2L, 5L, 6L)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                                                              -6L))
松英喆
2023-03-14

您可以使用group_modify()add_row()

library(dplyr)

df %>%
  group_by(id) %>%
  group_modify( ~ .x %>%
    summarise(name = toString(name), across(c(number, value), sum)) %>%
    add_row(.x, .)
  ) %>%
  ungroup()

# # A tibble: 6 × 4
#   id    name           number value
#   <chr> <chr>           <int> <int>
# 1 a     bob                 1     1
# 2 a     jane                2     2
# 3 a     bob, jane           3     3
# 4 b     mark                1     1
# 5 b     brittney            2     2
# 6 b     mark, brittney      3     3
 类似资料:
  • 问题内容: 有没有办法在单个查询中按类别和所有产品的总价获取所有产品的总价。 以下是查询,我正在使用按类别给出价格。 问题答案: 在查询中使用ROLLUP。 GROUP BY子句允许使用WITH 修饰符,从而将多余的行添加到摘要输出中。

  • 我有一个带有分组变量的数据帧,我想按组对它们求和。使用很容易。 但是现在我想要一个新的列,按组计算n1和n2的总和。这样地: 我如何使用dplyr? 编辑:实际上,这只是一个例子,我有很多变量。 我试过这两个代码,但它不在正确的维度上......

  • 问题内容: 快速提问,我有下表 我想将每个月的总数加起来,并按月对总数进行分组。例如, Jan- > 138 Feb-> 88.2 Apr-> 29.84 关于它的任何线索。谢谢 问题答案: 此解决方案将为您提供月份名称作为结果集的列,然后根据需要提供总数。

  • 问题内容: 给定以下数据框 我想按的总和对分组()进行排序,然后按(不对)的值进行分组。所以基本上得到组的顺序 然后通过对/错,最终看起来像这样: 如何才能做到这一点? 问题答案: Groupby A: 在每个组中,对B求和,然后使用transform广播值。然后按B排序: 通过从上方传递索引来索引原始df。这将按B值的总和对A值重新排序: 最后,使用选项保留“ A”组中的“ C”值,以保留步骤1

  • 问题内容: 我正在使用此数据框: 我想按名称然后按水果进行汇总,以获得每个名称的水果总数。 我尝试按名称和水果分组,但如何获取水果总数。 问题答案: 使用方法

  • 我正在使用此数据框: 我想通过名称和水果将其聚合,得到每个名称的水果总数。 我试着按名字和水果分组,但如何得到水果的总数呢。