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

在R中按列递增为多列名称重编码为数字(无循环实现)

问题描述

我有50列名称数据,为便于展示仅列出4列:

Name1       Name2         Name3      Name4
Rose,Ali    Van,Hall      Ghol,Dam   Murr,kate
Camp,Laura  Ka,Klo        Dan,Dan    Ali,Hoss
Rose,Ali    Van,Hall      Ghol,Dam   Kol,Kan
Murr,Kate   Ismal, Ismal  Sian,Rozi  Nas,Ami
Ghol,Dam    Ka,Klo        Rose,Ali   Nor,Ko
Murr,Kate   Ismal, Ismal  Dan,Dan    Nas,Ami

需求:按列依次为每个名称分配递增数字:

  • 第一列从1开始,重复名称使用相同数字;
  • 第二列从第一列的最大编号+1开始;
  • 后续每列均从前一列的最大编号+1开始,最终得到如下结果:
Assign1 Assign2 Assign3 Assign4
      1       5       8      12
      2       6       9      13
      1       5       8      14
      3       7      10      15
      4       6      11      17
      3       7       9      15

要求不使用循环,优先用sapply(示例参考:sapply(dat, function(x) match(x, unique(x)))),或dplyr/tidyverse工具实现。

解决方案

方法1:使用tidyverse(推荐)

利用长格式转换+分组计算,配合累计计算实现列间编号连续递增:

library(tidyverse)

# 构造示例数据
dat <- tibble(
  Name1 = c("Rose,Ali", "Camp,Laura", "Rose,Ali", "Murr,Kate", "Ghol,Dam", "Murr,Kate"),
  Name2 = c("Van,Hall", "Ka,Klo", "Van,Hall", "Ismal, Ismal", "Ka,Klo", "Ismal, Ismal"),
  Name3 = c("Ghol,Dam", "Dan,Dan", "Ghol,Dam", "Sian,Rozi", "Rose,Ali", "Dan,Dan"),
  Name4 = c("Murr,kate", "Ali,Hoss", "Kol,Kan", "Nas,Ami", "Nor,Ko", "Nas,Ami")
)

# 处理流程
result <- dat %>%
  mutate(row_id = row_number()) %>%
  pivot_longer(-row_id, names_to = "col", values_to = "name") %>%
  group_by(col) %>%
  mutate(local_id = match(name, unique(name))) %>%
  ungroup() %>%
  arrange(col) %>%
  mutate(col_order = as.integer(str_extract(col, "\\d+"))) %>%
  group_by(col) %>%
  mutate(offset = sum(head(unique(local_id), col_order - 1))) %>%
  ungroup() %>%
  mutate(final_id = local_id + offset) %>%
  pivot_wider(id_cols = row_id, names_from = col, values_from = final_id, names_prefix = "Assign") %>%
  select(-row_id)

# 查看结果
print(result, n = Inf)

方法2:使用sapply + 基础计算

通过sapply生成局部编号,再计算列偏移量并累加:

# 构造示例数据
dat <- data.frame(
  Name1 = c("Rose,Ali", "Camp,Laura", "Rose,Ali", "Murr,Kate", "Ghol,Dam", "Murr,Kate"),
  Name2 = c("Van,Hall", "Ka,Klo", "Van,Hall", "Ismal, Ismal", "Ka,Klo", "Ismal, Ismal"),
  Name3 = c("Ghol,Dam", "Dan,Dan", "Ghol,Dam", "Sian,Rozi", "Rose,Ali", "Dan,Dan"),
  Name4 = c("Murr,kate", "Ali,Hoss", "Kol,Kan", "Nas,Ami", "Nor,Ko", "Nas,Ami"),
  stringsAsFactors = FALSE
)

# 生成每列的局部编号
local_ids <- sapply(dat, function(x) match(x, unique(x)))

# 计算每列的起始偏移量
max_local <- apply(local_ids, 2, max)
offsets <- c(0, cumsum(max_local[-length(max_local)]))

# 计算最终编号
result <- t(t(local_ids) + offsets)
colnames(result) <- paste0("Assign", seq_len(ncol(result)))

# 查看结果
print(result)

两种方法均无循环,tidyverse方案更易读扩展,适合多列场景;sapply方案更简洁,适配基础R环境。

内容的提问来源于stack exchange,提问作者user330

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:35:25