R语言tidy管道工作流实现两组数据列对应相乘的方法
问题背景
开展调查研究数据处理时,需要将数据集中两组列按对应位置分别相乘。使用base R可以快速实现该操作,但未找到适配tidy风格、基于管道的工作流实现方案。现有公开的多数解决方案仅支持一组列与单个列相乘,无法满足两组多列对应相乘的需求。
base R实现参考代码如下:
library(tidyverse) df <- tibble( a1 = c(1, 2, 3, 4, 5), a2 = c(5, 4, 3, 2, 1), a3 = c(1, 5, 2, 4, 3), b1 = c(1, 1, 2, 1, 1), b2 = c(3, 3, 5, 4, 1), b3 = c(2, 1, 4, 2, 1) ) new_df <- df[, c("a1", "a2", "a3")] * df[, c("b1", "b2", "b3")] names(new_df) <- c("c1", "c2", "c3")
Tidy风格管道流实现方案
以下两种方法均完全适配%>%管道工作流,计算结果和base R实现完全一致:
方法1:dplyr原生实现(代码最简洁)
适合两组列有统一命名规律的场景,无需额外依赖包,自动按匹配规则生成新列:new_df <- df %>% mutate( # 同序号的a列与b列对应相乘,结果命名为c+序号 across(c(a1:a3), .names = "c{str_remove(.col, 'a')}") * across(c(b1:b3)) ) %>% # 不需要保留原a、b列时可加此步筛选结果 select(c1:c3)方法2:dplyr+purrr组合实现(鲁棒性最强)
不依赖列名规则,严格按照传入两组列的先后顺序对应位置相乘,逻辑和base R完全一致,适配列名无规律的场景:new_df <- df %>% mutate( map2_dfc( .x = pick(a1:a3), .y = pick(b1:b3), .f = ~.x * .y ) %>% set_names(c("c1", "c2", "c3")) ) %>% # 不需要保留原a、b列时可加此步筛选结果 select(c1:c3)
如果需要保留原始数据的所有列,只需要去掉代码末尾的select(c1:c3)语句,新生成的乘积列会自动追加到原数据框末尾。
内容的提问来源于stack exchange,提问作者Larry V
相关产品推荐
相关产品推荐

