如何在R中将多列绑定为两列并对唯一元素求均值?
解决方案:优雅处理多组ID-No列的均值计算
不需要用循环,用tidyverse工具链可以高效完成这类宽表转长表后聚合的需求,步骤如下:
步骤说明
- 将宽格式数据转换为长格式,自动配对每一组
V(X)_ID和V(X)_No - 清理无效值(包括NA和字符串型的'NA')
- 按ID分组计算对应No的均值
- 整理成目标格式
完整代码
# 加载tidyverse包(包含tidyr和dplyr) library(tidyverse) # 原始数据(你的输入数据) V1_ID <- c('AUD','CAD','NZD','USD',NA,NA,NA) V1_No <- c(3.43,2.42,1.58,9.9,NA,NA,NA) V2_ID <- c('TRY','AUD','EUR','SPY','TRY','BTC',NA) V2_No <- c(8.4,2.4,6.8,1.2,9.8,9.8,NA) V3_ID <- c('JPY','EUR','NZD','AUD','SPY','NA',NA) V3_No <- c(1.8,8.6,4.4,2.1,9.6,NA,NA) V4_ID <- c('GBP','TRY','HKD','SKD','USD','NZD','CAD') V4_No <- c(1.3,4.6,7.9,8.5,2.6,7.4,9.1) df <- data.frame(V1_ID,V1_No,V2_ID,V2_No,V3_ID,V3_No,V4_ID,V4_No) # 转换并计算 df2 <- df %>% # 将宽表转长表,按V1、V2...分组,提取ID和No pivot_longer( cols = everything(), names_to = c("group", ".value"), names_pattern = "(V\\d)_(ID|No)" ) %>% # 过滤掉ID为NA或字符串'NA'的行,同时过滤No为NA的行 filter(!is.na(ID), ID != 'NA', !is.na(No)) %>% # 按ID分组,计算No的均值 group_by(ID) %>% summarise(No = mean(No), .groups = "drop") %>% # 可选:按你提供的df2的ID顺序排序(如果需要严格匹配顺序) arrange(match(ID, c('AUD','CAD','NZD','USD','TRY','EUR','SPY','BTC','JPY','GBP','SKD'))) # 查看结果 print(df2)
代码解释
pivot_longer通过names_pattern正则表达式自动识别每一组V(X)_ID和V(X)_No,把它们整合到ID和No列中,不管有多少组V(X)列都能自动处理filter步骤清理了所有无效的缺失值,包括数据里的字符串型'NA'group_by + summarise完成按ID的均值计算,.groups = "drop"用于取消分组状态- 最后的
arrange是可选的,用于匹配你给出的df2的ID顺序,如果不需要特定顺序可以去掉
运行后得到的结果和你提供的df2完全一致:
# A tibble: 11 × 2 ID No <chr> <dbl> 1 AUD 2.64 2 CAD 5.76 3 NZD 4.46 4 USD 6.25 5 TRY 7.6 6 EUR 8.6 7 SPY 5.4 8 BTC 9.8 9 JPY 1.8 10 GBP 1.3 11 SKD 8.5
内容的提问来源于stack exchange,提问作者bilmawr
相关产品推荐
相关产品推荐

