在R中使用mutate和across将新列置于原列旁而非数据框末尾
在dplyr中让mutate+across生成的新列紧邻原列
我是R语言新手,想要用dplyr的mutate和across创建转换后的新列,但希望新列直接放在对应原列的旁边,而非追加到数据框末尾,同时不想用sort打乱原有列的顺序。
我尝试的代码和示例数据如下:
library(dplyr) df <- data.frame( data_in = 2:10, data_ft = 3:11, data_mile = 4:12 ) # 尝试的写法,新列被加到末尾,不符合预期 df_new <- df %>% mutate(across(contains("in"), ~ .x * 25.4, .names = "{sub('in', 'mm', col)}"))
我期望的列顺序是:data_in data_mm data_ft data_cm data_mile data_km。用across(everything(), ~ cbind(., .*2))能得到类似的紧邻顺序,但这种写法没法针对不同列设置不同转换系数,也不能自定义新列名,请问该怎么解决?
解决方案1:逐个处理并插入列(适合少量列)
这种方法逻辑直观,新手容易上手:对每一列生成新列后,用relocate把新列放到原列的后面。
library(dplyr) df <- data.frame( data_in = 2:10, data_ft = 3:11, data_mile = 4:12 ) df_new <- df %>% # 生成data_mm,放到data_in后面 mutate(data_mm = data_in * 25.4) %>% relocate(data_mm, .after = data_in) %>% # 生成data_cm,放到data_ft后面 mutate(data_cm = data_ft * 30.48) %>% relocate(data_cm, .after = data_ft) %>% # 生成data_km,放到data_mile后面 mutate(data_km = data_mile * 1.60934) %>% relocate(data_km, .after = data_mile) # 查看结果 df_new
解决方案2:批量处理+重排列序(适合大量列)
如果需要处理的列很多,可以先批量生成所有新列,再根据原列和新列的对应关系重新排列顺序:
library(dplyr) df <- data.frame( data_in = 2:10, data_ft = 3:11, data_mile = 4:12 ) # 定义转换规则:原列后缀 -> 新列后缀 + 转换系数 conv_rules <- list( in = list(suffix = "mm", coef = 25.4), ft = list(suffix = "cm", coef = 30.48), mile = list(suffix = "km", coef = 1.60934) ) # 第一步:批量生成所有新列 df_temp <- df %>% mutate(across( everything(), ~ { # 获取当前列名的后缀部分 col_suffix <- sub("data_", "", cur_column()) # 应用对应系数转换 . * conv_rules[[col_suffix]]$coef }, # 自定义新列名 .names = "{sub('in|ft|mile', function(x) conv_rules[[x]]$suffix, col)}" )) # 第二步:生成期望的列顺序(原列+对应新列配对) new_col_order <- unlist( lapply(names(df), function(col) { new_col <- sub("in|ft|mile", function(x) conv_rules[[x]]$suffix, col) c(col, new_col) }) ) # 按新顺序选择列 df_new <- df_temp %>% select(all_of(new_col_order)) # 查看结果 df_new
为什么原来的写法不符合预期?
你之前用across(contains("in"))的写法只会生成data_mm这一列,而mutate默认会把新生成的列追加到数据框末尾;而across(everything(), ~cbind(., .*2))是把每一列都转换成两列(原列+乘2的列),所以看起来顺序是对的,但这种写法没法针对不同列设置不同转换系数,也不能自定义新列名。
内容的提问来源于stack exchange,提问作者Coder_in_training
相关产品推荐
相关产品推荐

