如何在dplyr的mutate函数中使用动态变量选择数据列
问题根源
你原有代码的问题在于:直接写vector_of_names[position]只会返回对应位置的列名字符串,并不会被dplyr识别为提取对应列的实际值,因此得到的age列只会是字符格式的列名,而非你想要的数值。
解法1:tidyverse逐行处理(易理解,适合小数据)
用rowwise()按行分组后,通过cur_data()明确取当前行的对应列值,避免环境变量冲突:
library(dplyr) vector_of_names <- c("one","two","three") id <- c(1,2,3,4,5,6) position <- c(1,1,2,2,1,1) one <- c(32,34,56,77,87,98) two <- c(45,67,87,NA,33,56) three <- c(NA,NA,NA,NA,NA,60) data <- data.frame(id,position,one,two,three) result <- data %>% rowwise() %>% mutate(age = cur_data()[[vector_of_names[position]]]) %>% ungroup()
运行后得到的age列取值为 32, 34, 87, NA, 87, 98,符合需求。
解法2:矩阵索引法(高效,适合大数据量)
利用R的矩阵索引特性直接批量取值,不需要逐行运算,处理万行以上数据时速度优势明显:
data$age <- data[cbind(1:nrow(data), match(vector_of_names[data$position], colnames(data)))]
解法3:pick函数版本(dplyr 1.1.0+ 推荐)
如果你使用的是较新版本的dplyr,可以用pick函数更简洁地实现动态选列:
library(dplyr) library(purrr) result <- data %>% mutate(age = map2_dbl( row_number(), position, ~ pick(all_of(vector_of_names[.y]))[.x, ] ))
内容的提问来源于stack exchange,提问作者Richard Packer
相关产品推荐
相关产品推荐

