R中sapply返回矩阵而非字符向量的原因及数据框列替换修正方法
问题解答
1. sapply返回矩阵的原因
你调用sapply时迭代的是长度为4的序列1:4,每次迭代中gsub(ptr[[i]], p[[i]], var)会对**完整的var列(长度为4的向量)**做全局替换,每次返回长度为4的字符向量。sapply默认会将多次迭代返回的等长向量按列合并为4行4列的矩阵,dplyr的mutate接收到矩阵类型的输入时,会自动将矩阵的每一列拆分为独立的新字段,因此出现了var.1到var.4的多列输出。
2. 修正代码方案
方案1:使用命名匹配向量批量替换(最简洁,推荐)
无需循环,直接构造对应关系的命名向量,用stringr::str_replace_all一次性完成所有替换,符合dplyr的管道写法逻辑:
library(dplyr) library(stringr) # 构造替换对应关系:键为原值,值为替换后的值 replace_map <- c( "A_new_1" = "1_new_A", "B_new_2" = "2_new_B", "A_old_1" = "1_old_A", "B_old_2" = "2_old_B" ) # 批量替换 df_1 <- df_1 %>% mutate(var = str_replace_all(var, replace_map))
方案2:保留原有ptr、p结构的修正写法
如果你要保留已经定义好的ptr、p列表结构,可以直接转成命名映射后用recode实现替换:
library(dplyr) p <- list(c('1_new_A'), c('2_new_B'), c('1_old_A'), c('2_old_B')) ptr <- list(c('A_new_1'), c('B_new_2'), c('A_old_1'), c('B_old_2')) # 把列表转成recode可用的命名向量 replace_map <- setNames(unlist(p), unlist(ptr)) df_1 <- df_1 %>% mutate(var = recode(var, !!!replace_map))
运行后输出的结构符合要求:
> df_1 var code desc 1 1_new_A 1 applied 2 2_new_B 1 not applied 3 1_old_A 1 applied 4 2_old_B 1 applied
内容的提问来源于stack exchange,提问作者Vendetta
相关产品推荐
相关产品推荐

