You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:35:14