gpt4 book ai didi

R 在 purrr::map 中使用 dplyr::mutate() 而不复制行

转载 作者:行者123 更新时间:2023-12-01 10:17:44 24 4
gpt4 key购买 nike

这是数据:

library(tidyverse)
col_pre <- c('a', 'b', 'c')
df <- tibble(a1 = 1:3, a2 = 4:6, b1 = 7:9, b2 = 10:12, c1 = 13:15, c2 = 16:18)

我想使用 purrr::map()dplyr::mutate() 创建三个新列,它们是 df 中列的总和。我可以使用 map() 迭代 a、b、c 列前缀的向量。我弄清楚了 tidyeval 操作,以便下面的代码运行没有错误。

out <- col_pre %>%
map_df(~ df %>%
mutate(!!as.name(paste0(.x, '3')) := !!as.name(paste0(.x, '1')) + !!as.name(paste0(.x, '2')))
)

但是,out 现在有六个虚假行:

     a1    a2    b1    b2    c1    c2    a3    b3    c3
1 1 4 7 10 13 16 5 NA NA
2 2 5 8 11 14 17 7 NA NA
3 3 6 9 12 15 18 9 NA NA
4 1 4 7 10 13 16 NA 17 NA
5 2 5 8 11 14 17 NA 19 NA
6 3 6 9 12 15 18 NA 21 NA
7 1 4 7 10 13 16 NA NA 29
8 2 5 8 11 14 17 NA NA 31
9 3 6 9 12 15 18 NA NA 33

它所做的是不必要地复制输入 df 的三行。

这是我想要的输出:

     a1    a2    b1    b2   c1    c2    a3     b3    c3
1 1 4 7 10 13 16 5 17 29
2 2 5 8 11 14 17 7 19 31
3 3 6 9 12 15 18 9 21 33

我觉得 purrr::reduce() 可能是解决方案,但我不确定如何应用它。

感谢任何帮助!

最佳答案

我们可以在进行评估之前将字符串转换为 symbol,而不是 mutate 使用 transmute 然后将列与原始值绑定(bind)数据集

library(stringr)
library(purrr)
library(dplyr)
col_pre %>%
map_dfc(~ df %>%
transmute(!! str_c(.x, '3') := !! rlang::sym(str_c(.x, '1')) +
!! rlang::sym(str_c(.x, 2)))) %>%
bind_cols(df, .)
# A tibble: 3 x 9
# a1 a2 b1 b2 c1 c2 a3 b3 c3
# <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 1 4 7 10 13 16 5 17 29
#2 2 5 8 11 14 17 7 19 31
#3 3 6 9 12 15 18 9 21 33

或者另一个选项是 parse_exprs

df %>%
mutate(!!! rlang::parse_exprs(str_c(sprintf("%s1 + %s2",
col_pre, col_pre), collapse=";"))) %>%
rename_at(vars(contains("+")), ~ str_c(col_pre, 3))
# A tibble: 3 x 9
# a1 a2 b1 b2 c1 c2 a3 b3 c3
# <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 1 4 7 10 13 16 5 17 29
#2 2 5 8 11 14 17 7 19 31
#3 3 6 9 12 15 18 9 21 33

或者另一种选择是使用 pivot_longer 将其转换为“长”格式,然后进行计算

library(tidyr)
df %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_to = c(".value", "group"),
names_sep ="(?<=[a-z])(?=[0-9])") %>%
group_by(rn) %>%
summarise_at(vars(col_pre), list(`3` = sum)) %>%
select(-rn) %>%
bind_cols(df, .)

或者如果我们使用dplyrdevel版本('0.8.99.9000'),那么across可以与 summarise

一起使用
df %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_to = c(".value", "group"),
names_sep ="(?<=[a-z])(?=[0-9])") %>%
group_by(rn) %>%
summarise(across(col_pre, sum)) %>%
select(-rn) %>%
rename_all(~ str_c(., 3)) %>%
bind_cols(df, .)
# A tibble: 3 x 9
# a1 a2 b1 b2 c1 c2 a3 b3 c3
# <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 1 4 7 10 13 16 5 17 29
#2 2 5 8 11 14 17 7 19 31
#3 3 6 9 12 15 18 9 21 33

关于R 在 purrr::map 中使用 dplyr::mutate() 而不复制行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59656060/

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