在R语言中从一对多DataFrame生成匹配向量及右侧相邻列数据
解决方案:根据ID匹配列并提取相邻列值
下面提供两种无需循环的高效实现方式,均能满足你的需求:
方法一:Base R 原生实现
利用矩阵索引直接定位目标值,是最轻量化的解决方案:
# 构造原始数据框 df <- data.frame( id = c('A','A','A','B','B','C'), A = c(1,2,3,4,5,6), B = c(7,8,9,10,11,12), C = c(13,14,15,16,17,18), D = c(19,20,21,22,23,24) ) # 1. 提取与id匹配列的对应值 match_vals <- df[cbind(seq(nrow(df)), match(df$id, colnames(df)))] # 2. 提取匹配列右侧相邻列的对应值 adj_col_pos <- match(df$id, colnames(df)) + 1 adj_vals <- df[cbind(seq(nrow(df)), adj_col_pos)] # 3. 合并为最终结果 result <- data.frame(match_val = match_vals, adj_val = adj_vals) print(result)
运行后输出:
match_val adj_val 1 1 7 2 2 8 3 3 9 4 10 16 5 11 17 6 18 24
方法二:Tidyverse 实现(更易读)
如果习惯tidy风格的代码,可以用dplyr+tidyr完成,逻辑更直观:
library(dplyr) library(tidyr) # 构造原始数据框 df <- data.frame( id = c('A','A','A','B','B','C'), A = c(1,2,3,4,5,6), B = c(7,8,9,10,11,12), C = c(13,14,15,16,17,18), D = c(19,20,21,22,23,24) ) # 转为长格式并标记列位置 long_df <- df %>% pivot_longer(-id, names_to = "col_name", values_to = "value") %>% mutate(col_pos = match(col_name, colnames(df))) # 提取匹配列的值 match_df <- long_df %>% filter(col_name == id) %>% select(id, match_val = value) # 提取相邻列的值 adj_df <- long_df %>% left_join(match_df %>% mutate(adj_col_pos = match(df$id, colnames(df)) + 1), by = "id") %>% filter(col_pos == adj_col_pos) %>% select(id, adj_val = value) # 合并结果 result_tidy <- match_df %>% left_join(adj_df, by = "id") %>% select(match_val, adj_val) print(result_tidy)
输出结果与Base R方法完全一致。
内容的提问来源于stack exchange,提问作者James Vercammen
相关产品推荐
相关产品推荐

