You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中用map对列表内tibble指定分组行的n值求和

需求与问题描述

我有大量存储在列表中的计数表数据,部分行需要按指定标签聚合。简化示例数据如下:

# 构造示例数据
df <- list(
  x1 = tibble::tibble(
    fruits = c("apple", "orange", "banana", "pineapple"),
    n = sample(1:10, 4)
  ),
  x2 = tibble::tibble(
    fruits = c("apple", "orange", "banana", "pineapple"),
    n = sample(1:10, 4)
  )
)

输出结果:

#> $x1
#> # A tibble: 4 × 2
#>   fruits        n
#>   <chr>     <int>
#> 1 apple         4
#> 2 orange        3
#> 3 banana        2
#> 4 pineapple     1
#> 
#> $x2
#> # A tibble: 4 × 2
#>   fruits        n
#>   <chr>     <int>
#> 1 apple         8
#> 2 orange        5
#> 3 banana        7
#> 4 pineapple     6

需要将包含"apple"的行标记为"--",处理后的数据集df2如下:

df2 <- 
df |> 
  purrr::map(\(x) {
    x |> 
      dplyr::mutate(across(1, \(i) {
        ifelse(stringr::str_detect(i, "apple"), "--", i)
      }))
  })

输出结果:

#> $x1
#> # A tibble: 4 × 2
#>   fruits     n
#>   <chr>  <int>
#> 1 --         4
#> 2 orange     3
#> 3 banana     2
#> 4 --         1
#> 
#> $x2
#> # A tibble: 4 × 2
#>   fruits     n
#>   <chr>  <int>
#> 1 --         8
#> 2 orange     5
#> 3 banana     7
#> 4 --         6

现在需要对fruits列为"--"的行的n值求和,尝试用map结合summarise实现,但得到错误结果:

df2 |> 
  purrr::map(\(x) {
    x |> 
      dplyr::summarise(across(2, \(i) {
        n = sum(n)
        .by = fruits
      }))
  })

输出结果(含警告):

#> Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in
#> dplyr 1.1.0.
#> ℹ Please use `reframe()` instead.
#> ℹ When switching from `summarise()` to `reframe()`, remember that `reframe()`
#>   always returns an ungrouped data frame and adjust accordingly.
#> Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in
#> dplyr 1.1.0.
#> ℹ Please use `reframe()` instead.
#> ℹ When switching from `summarise()` to `reframe()`, remember that `reframe()`
#>   always returns an ungrouped data frame and adjust accordingly.
#> $x1
#> # A tibble: 4 × 1
#>   n     
#>   <chr> 
#> 1 --    
#> 2 orange
#> 3 banana
#> 4 --    
#> 
#> $x2
#> # A tibble: 4 × 1
#>   n     
#>   <chr> 
#> 1 --    
#> 2 orange
#> 3 banana
#> 4 --

改用reframe后结果仍一致,请问正确实现方法是什么?


正确实现方法

你的错误在于summarise的语法使用不当:.by参数应该作为summarise的顶层参数,而非放在across内部;同时across里的逻辑错误,误将fruits的标签赋值给了n列。

以下是两种简洁的实现方式:

方法一:保留所有分组的聚合

直接按fruits分组,对n列求和,会保留所有分组(包括"--"、"orange"、"banana"):

df2 |> 
  purrr::map(\(x) {
    x |> 
      dplyr::summarise(n = sum(n), .by = fruits)
  })

输出结果:

#> $x1
#> # A tibble: 3 × 2
#>   fruits     n
#>   <chr>  <int>
#> 1 --         5
#> 2 orange     3
#> 3 banana     2
#> 
#> $x2
#> # A tibble: 3 × 2
#>   fruits     n
#>   <chr>  <int>
#> 1 --        14
#> 2 orange     5
#> 3 banana     7

方法二:仅聚合指定分组

如果只需要"--"分组的求和结果,可以先筛选再聚合:

df2 |> 
  purrr::map(\(x) {
    x |> 
      dplyr::filter(fruits == "--") |> 
      dplyr::summarise(fruits = "--", n = sum(n))
  })

输出结果:

#> $x1
#> # A tibble: 1 × 2
#>   fruits     n
#>   <chr>  <int>
#> 1 --         5
#> 
#> $x2
#> # A tibble: 1 × 2
#>   fruits     n
#>   <chr>  <int>
#> 1 --        14

补充说明

如果习惯传统分组写法,也可以用group_by + summarise实现,效果和方法一一致:

df2 |> 
  purrr::map(\(x) {
    x |> 
      dplyr::group_by(fruits) |> 
      dplyr::summarise(n = sum(n)) |> 
      dplyr::ungroup()
  })

内容的提问来源于stack exchange,提问作者ryoto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:12:10