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

R语言宽表转长表:无需指定TIME、TAB变量能否实现HAVE转WANT?

自动提取时变前缀实现数据重塑

现有R语言中的HAVE数据集与目标WANT数据集如下:

原始数据集(HAVE)

library(data.table)
HAVE = fread("
STUDENT CLASS GROUP S1TIME S2TIME S3TIME H2TAB H4TAB H5TAB
1 0 2 NA NA 6 NA 7 5
2 0 7 4 NA 4 5 NA 2
3 1 5 NA 4 5 6 NA NA
")

目标数据集(WANT)

WANT = data.frame(
  STUDENT = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3),
  INPUT = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5),
  CLASS = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1),
  GROUP = c(2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5),
  S.TIME = c(NA, NA, 6, NA, NA, 4, NA, 4, NA, NA, NA, 4, 5, NA, NA),
  H.TAB = c(NA, NA, NA, 7, 5, NA, 5, NA, NA, 2, NA, 6, NA, NA, NA)
)

问题

能否在不指定TIME、TAB这类后缀关键词的前提下,将HAVE转换为WANT?希望自动提取时变前缀(stubs)并完成完整的数据重塑。


可以实现,核心思路是通过正则表达式自动识别变量名中的字母前缀(如S、H)和数字序号,先转长表拆分变量信息,再补全所有INPUT的完整序列,最后转回宽表。以下是两种可行方案:

方案1:使用data.table(适配原代码的fread)

library(data.table)

# 1. 转长表,保留标识变量
long_dt = melt(HAVE, id.vars = c("STUDENT", "CLASS", "GROUP"), 
               variable.name = "var", value.name = "val")

# 2. 拆分变量名:分离字母前缀和数字INPUT编号
long_dt[, c("stub", "input") := tstrsplit(var, "(?<=[A-Za-z])(?=[0-9])", perl = TRUE)]
long_dt[, input := as.integer(input)]
long_dt[, var := NULL]

# 3. 生成所有INPUT的完整组合(1-5),确保每个学生都有5行
full_inputs = CJ(STUDENT = unique(long_dt$STUDENT), INPUT = 1:5)

# 4. 合并数据并转回宽表
result = merge(full_inputs, long_dt, 
               by.x = c("STUDENT", "INPUT"), by.y = c("STUDENT", "input"), 
               all.x = TRUE)
result = dcast(result, STUDENT + INPUT + CLASS + GROUP ~ stub, value.var = "val")

# 5. 重命名列以匹配目标格式,排序
setnames(result, c("S", "H"), c("S.TIME", "H.TAB"))
setorder(result, STUDENT, INPUT)

方案2:使用tidyverse

library(tidyverse)

HAVE %>%
  # 转长表
  pivot_longer(cols = -c(STUDENT, CLASS, GROUP), names_to = "var", values_to = "val") %>%
  # 拆分变量名,自动转换数字类型
  separate(var, into = c("stub", "input"), sep = "(?<=[A-Za-z])(?=[0-9])", convert = TRUE) %>%
  # 补全所有INPUT的行,缺失值填NA
  complete(STUDENT, INPUT = 1:5, fill = list(val = NA)) %>%
  # 转回宽表
  pivot_wider(names_from = stub, values_from = val) %>%
  # 重命名列并排序
  rename(S.TIME = S, H.TAB = H) %>%
  arrange(STUDENT, INPUT)

两种方案都无需手动指定TIME或TAB后缀,完全自动识别时变前缀,最终输出结构与WANT一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:47:41