【问题标题】:map over tibble columns while preserving groups在保留组的同时映射 tibble 列
【发布时间】:2021-05-09 22:45:24
【问题描述】:

我有一个分组的小标题。我想使用 map() 来遍历 tibble 的列。在每一列中,我希望map() 对每个组分别采取行动。换句话说,我希望map() 尊重 tibble 的分组结构。

但是map() 似乎并不尊重小标题的分组结构。这是一个最小的例子:

library(dplyr)
library(purrr)
data(iris)
iris %>%
  group_by(Species) %>%
  map(length)

在 iris 数据集中,有 3 个物种和 4 列(不包括“物种”)。因此,我希望 map() 返回一个 3 × 4 = 12 个长度的列表,或者返回一个总共有 12 个长度的嵌套列表。但它返回一个包含 5 个元素的列表:每列一个,计算分组列。这五个元素中的每一个都是一列的总长度 (150)。如何调整上面的代码以提供我想要的结果?

在这个最小的例子中,使用map() 的一个令人满意的替代方法是

iris %>%
  group_by(Species) %>%
  summarize(
    mutate(across(everything(), length))
  )

返回

# A tibble: 3 x 5
  Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
* <fct>             <int>       <int>        <int>       <int>
1 setosa               50          50           50          50
2 versicolor           50          50           50          50
3 virginica            50          50           50          50

但在大多数情况下,这种替代方法行不通。问题是我通常希望summarize()mutate 返回loess() 对象,而不是整数。当我试图让他们返回 loess() 对象时,他们会因类似的错误而窒息

Error: Problem with `summarise()` input `..1`.
x Input must be a vector, not a `loess` object.

【问题讨论】:

    标签: r dplyr functional-programming purrr


    【解决方案1】:

    do 允许您一次在一个组中工作

    编辑:正如您所说,do 已被取代,这是更直接(和鼓励)的方式。 (我在do 回答之前尝试过的问题是我错过了cur_data() 的使用。)

    colnms <- names(iris)[2:4]
    colnms
    # [1] "Sepal.Width"  "Petal.Length" "Petal.Width" 
    
    iris %>%
      group_by(Species) %>%
      summarize(
        other = colnms,
        mdl = map(colnms, ~ loess(as.formula(paste("Sepal.Length ~", .x)),
                                  data = cur_data()))
      )
    # Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  :
    #   pseudoinverse used at 0.0975
    # Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  :
    #   neighborhood radius 0.2025
    # Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  :
    #   reciprocal condition number  2.8298e-016
    # Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  :
    #   There are other near singularities as well. 0.01
    # # A tibble: 9 x 3
    # # Groups:   Species [3]
    #   Species    other        mdl    
    #   <fct>      <chr>        <list> 
    # 1 setosa     Sepal.Width  <loess>
    # 2 setosa     Petal.Length <loess>
    # 3 setosa     Petal.Width  <loess>
    # 4 versicolor Sepal.Width  <loess>
    # 5 versicolor Petal.Length <loess>
    # 6 versicolor Petal.Width  <loess>
    # 7 virginica  Sepal.Width  <loess>
    # 8 virginica  Petal.Length <loess>
    # 9 virginica  Petal.Width  <loess>
    

    【讨论】:

    • 谢谢@r2evans。那看起来不错。不过,我注意到do() has been superseded;我担心它很快就会从 dplyr 包中删除。 / ?do 文档说do() 已被summarize()nest_by()across() 的组合所取代。我将进一步研究这些命令,尤其是nest_by(),看看它是否有帮助。但再次感谢您提醒我注意do()
    • 看看我的编辑,我想这会为你做的:-)
    • 谢谢您,这太棒了。我不知道cur_data()。看起来很有用。
    猜你喜欢
    • 2011-09-25
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2021-06-09
    相关资源
    最近更新 更多