如何实现:取C开头列最大值对应A列值,从B列中减得新列?
需求实现方案与函数使用说明
原始数据
A1 A2 A3 A4 B C1 C2 C3 C4 1 3 2 2 7 2 NA 6 9 4 6 12 1 3 1 6 5 2 6 1 NA 1 7 3 2 2 1
需求说明
对每一行执行以下操作:
- 找出所有以C开头的列中的最大值(忽略NA)
- 获取该最大值所在列的后缀数字(比如C4的后缀是4)
- 匹配对应后缀的A列(比如后缀4对应A4)
- 用B列的值减去该A列的值,得到新列
new
问题解答
1. 需求是否可实现?
完全可以实现,下面给出基于R语言tidyverse工具包的具体实现代码。
2. 是否可以使用starts_with()函数完成?
是的,starts_with()是tidyverse中用于按列名前缀筛选列的函数,刚好可以快速选中所有A开头和C开头的列,非常适配这个需求。
具体实现代码(R语言)
library(dplyr) library(stringr) # 构造示例数据 df <- tibble( A1 = c(1, 4, 6), A2 = c(3, 6, 1), A3 = c(2, 12, NA), A4 = c(2, 1, 1), B = c(7, 3, 7), C1 = c(2, 1, 3), C2 = c(NA, 6, 2), C3 = c(6, 5, 2), C4 = c(9, 2, 1) ) # 计算new列 df_result <- df %>% rowwise() %>% mutate( # 找到C开头列中最大值的位置(自动忽略NA) max_c_col_pos = which.max(c_across(starts_with("C"))), # 提取对应列的后缀数字 suffix = as.numeric(str_extract(names(select(., starts_with("C")))[max_c_col_pos], "\\d+")), # 匹配对应的A列并计算new值 new = B - pull(select(., starts_with("A"))[, suffix]) ) %>% ungroup() # 查看结果 print(df_result)
代码说明
starts_with("C")和starts_with("A")分别筛选出所有C开头和A开头的列,无需手动输入列名,适配列名有规律的场景。rowwise()让后续计算按行执行,保证每行单独处理最大值。c_across()配合starts_with("C")获取每行的C列数据,which.max()自动忽略NA并找出最大值的位置。str_extract()从C列列名中提取后缀数字,用来匹配对应的A列。pull()取出对应A列的值,最终计算B - A列值得到new列。
运行代码后得到的结果和示例一致:
# A tibble: 3 × 10 A1 A2 A3 A4 B C1 C2 C3 C4 new <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 3 2 2 7 2 NA 6 9 5 2 4 6 12 1 3 1 6 5 2 -3 3 6 1 NA 1 7 3 2 2 1 1
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

