如何用dplyr/purrr按指定变量及对应水平将字符数据转为因子
错误原因
map2报错的核心原因是管道符默认将左侧dat作为.x参数传入map2。数据框本质是列的列表,长度等于列数(示例中dat共6列),而你传入的变量名、对应水平列表长度均为2,三者长度不匹配,触发长度校验报错。- across支持传入变量对应的自定义水平,可通过
cur_column()获取当前处理的列名,匹配对应水平即可实现。
实现方案
方案1:dplyr + across 实现(推荐)
逻辑最简洁,符合tidyverse常用写法:
library(tidyverse) dat3 <- dat %>% mutate( # 遍历所有需要转因子的变量 across(all_of(factor_map2$var), # 用cur_column()获取当前列名,匹配对应的水平列表 ~ factor(.x, levels = factor_map2$levels[match(cur_column(), factor_map2$var)][[1]])) ) # 如果需要生成有序因子(匹配Likert量表这类有序响应需求),替换为ordered函数即可: # ~ ordered(.x, levels = factor_map2$levels[match(cur_column(), factor_map2$var)][[1]])
方案2:purrr + reduce2 实现
和你原有for循环逻辑完全一致,是迭代修改数据集的思路:
dat4 <- reduce2( .x = factor_map2$var, .y = factor_map2$levels, .f = function(current_df, col_name, level_list) { current_df[[col_name]] <- factor(current_df[[col_name]], levels = level_list) return(current_df) }, .init = dat # 初始数据集 )
结果验证
两种方案输出结果和原有for循环输出完全一致:
identical(dat2, dat3) # [1] TRUE identical(dat2, dat4) # [1] TRUE
内容的提问来源于stack exchange,提问作者Lief Esbenshade
相关产品推荐
相关产品推荐

