我有一个分组标题。我想使用map()
来遍历标题的列。在每一列中,我想让map()
分别作用于每一个基团。换句话说,我希望map()
尊重标题的分组结构。
但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.
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>