按组和总和创建组合

BHu*_*son 5 combinations r dataframe dplyr

我有 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
Run Code Online (Sandbox Code Playgroud)

我想创建 的所有组合name,无论有多少个,并将它们粘贴在一起并用逗号分隔,并对每个组合中的number和求和。上例所需的输出是:valueid

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
Run Code Online (Sandbox Code Playgroud)

谢谢大家!

Dar*_*sai 5

你可以使用group_modify()+ add_row()

\n
library(dplyr)\n\ndf %>%\n  group_by(id) %>%\n  group_modify( ~ .x %>%\n    summarise(name = toString(name), across(c(number, value), sum)) %>%\n    add_row(.x, .)\n  ) %>%\n  ungroup()\n\n# # A tibble: 6 \xc3\x97 4\n#   id    name           number value\n#   <chr> <chr>           <int> <int>\n# 1 a     bob                 1     1\n# 2 a     jane                2     2\n# 3 a     bob, jane           3     3\n# 4 b     mark                1     1\n# 5 b     brittney            2     2\n# 6 b     mark, brittney      3     3\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我不认为这解决了操作员的问题——他们要求组合案例。OP 示例数据和输出可能有点太少了。 (2认同)

H 1*_*H 1 4

您可以使用创建成对索引combn()并使用这些索引扩展数据框slice()。然后只需按这些行对进行分组并进行总结即可。我假设您想要成对组合,但如果需要,这可以适用于更大的组合。包含一些处理组 < 2 的代码,但如果数据中不存在这些代码,则可以将其删除。

\n
library(dplyr)\nlibrary(purrr)\n\ndf1 %>%\n  group_by(id) %>%\n  slice(c(combn(seq(n()), min(n(), 2)))) %>%\n  mutate(id2 = (row_number()-1) %/% 2) %>%\n  group_by(id, id2) %>%\n  summarise(name = toString(name),\n            across(where(is.numeric), sum), .groups = "drop") %>%\n  select(-id2) %>%\n  bind_rows(df1 %>%\n              group_by(id) %>%\n              filter(n() > 1), .) %>%\n  arrange(id) %>%\n  ungroup()\n\n# A tibble: 6 \xc3\x97 4\n  id    name           number value\n  <chr> <chr>           <int> <int>\n1 a     bob                 1     1\n2 a     jane                2     2\n3 a     bob, jane           3     3\n4 b     mark                1     1\n5 b     brittney            2     2\n6 b     mark, brittney      3     3\n
Run Code Online (Sandbox Code Playgroud)\n

编辑:

\n

要适应所有可能的组合,您可以迭代这些值直至最大组大小。使用已编辑的数据,其中将几行添加到第一组:

\n
map_df(seq(max(table(df2$id))), ~\n         df2 %>%\n         group_by(id) %>%\n         slice(c(combn(seq(n()), .x * (.x <= n())))) %>%\n         mutate(id2 = (row_number() - 1) %/% .x) %>%\n         group_by(id, id2) %>%\n         summarise(name = toString(name),\n                   across(where(is.numeric), sum), .groups = "drop")\n       ) %>%\n  select(-id2) %>%\n  arrange(id)\n\n# A tibble: 18 \xc3\x97 4\n   id    name                      number value\n   <chr> <chr>                      <int> <int>\n 1 a     bob                            1     1\n 2 a     jane                           2     2\n 3 a     sophie                         1     1\n 4 a     jeremy                         2     2\n 5 a     bob, jane                      3     3\n 6 a     bob, sophie                    2     2\n 7 a     bob, jeremy                    3     3\n 8 a     jane, sophie                   3     3\n 9 a     jane, jeremy                   4     4\n10 a     sophie, jeremy                 3     3\n11 a     bob, jane, sophie              4     4\n12 a     bob, jane, jeremy              5     5\n13 a     bob, sophie, jeremy            4     4\n14 a     jane, sophie, jeremy           5     5\n15 a     bob, jane, sophie, jeremy      6     6\n16 b     mark                           3     5\n17 b     brittney                       4     6\n18 b     mark, brittney                 7    11\n
Run Code Online (Sandbox Code Playgroud)\n

数据df2

\n
df2 <- structure(list(id = c("a", "a", "a", "a", "b", "b"), name = c("bob", \n                                                                     "jane", "sophie", "jeremy", "mark", "brittney"), number = c(1L, \n                                                                                                                                 2L, 1L, 2L, 3L, 4L), value = c(1L, 2L, 1L, 2L, 5L, 6L)), class = "data.frame", row.names = c(NA, \n                                                                                                                                                                                                                              -6L))\n
Run Code Online (Sandbox Code Playgroud)\n