如何在R语言中利用替换值数据框替换另一数据框中的值?
问题描述
我有一个数据框:
df <- structure(list(X1 = 1:2, X2 = c(1L, 3L), X3 = 2:3), class = "data.frame", row.names = c(NA, -2L))
输出如下:
X1 X2 X3 1 1 1 2 2 2 3 3
还有一个包含替换值的数据框:
replacement_values <- structure(list(num = c("1", "2", "3"), . = c("cat", "dog", "mouse")), row.names = c(NA, -3L), class = "data.frame")
输出如下:
num . 1 1 cat 2 2 dog 3 3 mouse
需求是将第一个数据框中的所有1替换为cat,2替换为dog,3替换为mouse,最终得到:
X1 X2 X3 1 cat cat dog 2 dog mouse mouse
我之前用的方法十分繁琐且未用到replacement_values数据框:
df <- df %>% dplyr::mutate( X1 = X1 %>% gsub("1", "cat", .) %>% gsub("2", "dog", .) %>% gsub("3", "mouse", .), X2 = X2 %>% gsub("1", "cat", .) %>% gsub("2", "dog", .) %>% gsub("3", "mouse", .), X3 = X3 %>% gsub("1", "cat", .) %>% gsub("2", "dog", .) %>% gsub("3", "mouse", .) )
请问有没有更优的实现方式?
优化实现方法
方法1:dplyr + 命名向量(推荐)
先将替换规则数据框转换为命名向量,再用across()批量处理所有列,既简洁又能复用replacement_values:
library(dplyr) # 将替换规则转为命名向量:名字是原始数值,值是替换后的文本 replace_vec <- setNames(replacement_values$. , as.integer(replacement_values$num)) # 批量替换所有列 df_new <- df %>% mutate(across(everything(), ~recode(., !!!replace_vec)))
运行后得到目标结果:
X1 X2 X3 1 cat cat dog 2 dog mouse mouse
方法2:因子类型映射
利用因子的levels和labels属性直接完成映射,适合一对一替换场景:
library(dplyr) # 转换为因子后再转回字符型(避免结果是因子类型) df_new <- df %>% mutate(across(everything(), ~as.character(factor(., levels = replacement_values$num, labels = replacement_values$.))))
方法3:Base R 批量处理
如果不使用tidyverse工具,可以用lapply()结合命名向量实现:
# 创建替换映射 replace_map <- setNames(replacement_values$. , replacement_values$num) # 遍历所有列完成替换 df_new <- as.data.frame(lapply(df, function(col) replace_map[as.character(col)]))
方法4:purrr函数式处理
习惯purrr风格的话,可以用map_chr()批量处理每一列:
library(purrr) library(dplyr) replace_vec <- setNames(replacement_values$. , as.integer(replacement_values$num)) df_new <- df %>% mutate(across(everything(), ~map_chr(., ~replace_vec[as.character(.)])))
内容的提问来源于stack exchange,提问作者icedcoffee
相关产品推荐
相关产品推荐

