R语言如何按行列向量逐行配对提取data.frame对应值
R逐行配对提取data.frame指定行列值的方法
问题场景
给定分别存储行索引、列名的两个向量,需要逐组匹配提取R中data.frame的对应值,以内置数据集mtcars为例,数据集前10行结构如下:
mpg cyl disp hp drat wt qsec vs am gear carb Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 ...
最初尝试用如下代码实现需求:
data.frame(row = c(1, 3, 5), col = c('mpg', 'cyl', 'disp')) |> mutate(value = mtcars[row, col])
预期得到逐行匹配的结果:
row col value 1 1 mpg 21.0 2 3 cyl 4 3 5 disp 360.0
实际运行返回了指定行、指定列的全量交叉取值,返回3行3列的结果,不符合预期:
row col value.mpg value.cyl value.disp 1 1 mpg 21.0 6 160 2 3 cyl 22.8 4 108 3 5 disp 18.7 8 360
问题原因
R里data.frame的[行索引, 列索引]语法有个默认规则:如果行、列位置传入两个独立的等长向量,不会按顺序逐行配对取数,而是会提取两个向量所有元素交叉组合对应的单元格,所以最后返回的是3行3列的切片,不是预期的3个单值。
可行实现方案
- 基础R矩阵索引法(性能最优)
R原生支持两列矩阵作为data.frame的索引输入,矩阵第一列为行位置,第二列为列名/列位置,会自动逐行配对取值,不需要加载第三方包,执行效率最高:
# 构造行列配对表 idx_df <- data.frame(row = c(1, 3, 5), col = c('mpg', 'cyl', 'disp')) # 转换为矩阵后直接索引取值 idx_df$value <- mtcars[as.matrix(idx_df)]
运行后直接得到预期输出。
- tidyverse逐行运算方法
如果使用dplyr工作流,需要显式加rowwise()声明按行运算,否则mutate会将整列向量传入索引逻辑,触发之前的交叉取值问题:
library(dplyr) data.frame(row = c(1, 3, 5), col = c('mpg', 'cyl', 'disp')) |> rowwise() |> # 关键:声明逐行处理 mutate(value = mtcars[row, col]) |> ungroup() # 取消逐行分组,方便后续操作
- 基础R映射方法
用mapply逐组传入行、列参数取值,同样不需要依赖第三方包:
idx_df <- data.frame(row = c(1, 3, 5), col = c('mpg', 'cyl', 'disp')) idx_df$value <- mapply(function(r, c) mtcars[r, c], idx_df$row, idx_df$col)
内容的提问来源于stack exchange,提问作者user1
相关产品推荐
相关产品推荐

