gpt4 book ai didi

r - 按列位置将函数参数传递给 mutate_at

转载 作者:行者123 更新时间:2023-12-04 00:59:43 26 4
gpt4 key购买 nike

我正在尝试收紧 %>%管道工作流,我需要将相同的函数应用于多列,但每次更改一个参数。我觉得purrrmapinvoke函数应该会有所帮助,但我无法理解它。

我的数据框包含预期生命周期、贫困率和家庭收入中位数的列。我可以将所有这些列名传递给 varsmutate_at , 使用 round作为应用于每个的函数,并可选择提供 digits争论。但是我想不出一种方法,如果存在的话,可以为 digits 传递不同的值与每一列相关联。我希望预期生命周期四舍五入为 1 位数,贫困四舍五入为 2,收入四舍五入为 0。

我可以打电话mutate在每一列上,但考虑到我可能有更多列都接收相同的功能,只更改了一个附加参数,我想要更简洁的东西。

library(tidyverse)

df <- tibble::tribble(
~name, ~life_expectancy, ~poverty, ~household_income,
"New Haven", 78.0580437642378, 0.264221051111753, 42588.7592521085
)

在我的想象中,我可以做这样的事情:

df %>%
mutate_at(vars(life_expectancy, poverty, household_income),
round, digits = c(1, 2, 0))

但是得到错误

Error in mutate_impl(.data, dots) : Column life_expectancy must be length 1 (the number of rows), not 3



使用 mutate_at而不是 mutate只是为了与我的理想情况具有相同的语法:

df %>%
mutate_at(vars(life_expectancy), round, digits = 1) %>%
mutate_at(vars(poverty), round, digits = 2) %>%
mutate_at(vars(household_income), round, digits = 0)
#> # A tibble: 1 x 4
#> name life_expectancy poverty household_income
#> <chr> <dbl> <dbl> <dbl>
#> 1 New Haven 78.1 0.26 42589

数字映射使用每个 digits每列的选项,而不是按位置,给我 3 行,每行四舍五入到不同的位数。

df %>%
mutate_at(vars(life_expectancy, poverty, household_income),
function(x) map(x, round, digits = c(1, 2, 0))) %>%
unnest()
#> # A tibble: 3 x 4
#> name life_expectancy poverty household_income
#> <chr> <dbl> <dbl> <dbl>
#> 1 New Haven 78.1 0.3 42589.
#> 2 New Haven 78.1 0.26 42589.
#> 3 New Haven 78 0 42589

创建于 2018-11-13 由 reprex package (v0.2.1)

最佳答案

2 解决方案

mutate!!!
invoke是个好主意,但现在大多数人都不需要它 tidyverse功能支持!!!运算符(operator),这是您可以执行的操作:

digits <- c(life_expectancy = 1, poverty = 2, household_income = 0)  
df %>% mutate(!!!imap(digits, ~round(..3[[.y]], .x),.))
# # A tibble: 1 x 4
# name life_expectancy poverty household_income
# <chr> <dbl> <dbl> <dbl>
# 1 New Haven 78.1 0.26 42589
..3是初始数据帧,作为第三个参数通过调用结束时的点传递给函数。

写得更明确:
df %>% mutate(!!!imap(
digits,
function(digit, name, data) round(data[[name]], digit),
data = .))

如果您需要从旧界面开始(尽管我建议的界面会更灵活),请先执行以下操作:
digits <- setNames(c(1, 2, 0), c("life_expectancy", "poverty", "household_income"))

mutate_at<<-

在这里,我们稍微弯曲了避免 <<- 的好习惯。只要有可能,但可读性很重要,而且这个真的很容易阅读。
digits <- c(1, 2, 0)
i <- 0
df %>%
mutate_at(vars(life_expectancy, poverty, household_income), ~round(., digits[i<<- i+1]))
# A tibble: 1 x 4
# name life_expectancy poverty household_income
# <chr> <dbl> <dbl> <dbl>
# 1 New Haven 78.1 0.26 42589

(或者只是 df %>% mutate_at(names(digits), ~round(., digits[i<<- i+1])) 如果您在我的第一个解决方案中使用命名向量)

关于r - 按列位置将函数参数传递给 mutate_at,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53288100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com