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

如何在R中将含数值与字符型数据的宽表转为重复实例长表?

问题:R语言宽格式数据集转长格式

我是R语言新手,想把手头的宽格式数据集转换成包含重复实例的长格式。

补充信息:可复现数据结构

structure(list(record_id = 1:6, subjectid = c("M001", "M002", 
"M003", "M004", "M005", "M006"), interviewid_1 = c(349976L, 351977L, 
NA, 349979L, 349980L, 349981L), endtime_1 = c("7/8/2021 17:02", 
"8/24/2021 16:48", "", "7/15/2021 16:32", "7/8/2021 16:06", "7/8/2021 15:09"
), cjanx_1 = c(33.83, 53.99, NA, 74.63, 38.85, 70.59), cjanx_cat_1 = c("Normal", 
"Moderate", "", "Severe", "Mild", "Severe"), cjanx_duration_1 = c(79.491, 
68.437, NA, 43.784, 145.51, 57.151), cjdep_1 = c(30.76, 62.59, 
NA, 75.91, 50.36, 62.59), cjdep_cat_1 = c("Normal", "Mild", "", 
"Severe", "Mild", "Mild"), cjdep_duration_1 = c(81.288, 63.692, 
NA, 81.121, 123.557, 61.212), cjss_1 = c(28.06, 50.88, NA, 59.62, 
37.77, 30.34)), row.names = c(NA, 6L), class = "data.frame")

期望输出格式

SubjID           Time_1      Anx   Anx_Cat    Dep    Dep_Cat
  M001   12/12/2002 11:30PM   80     Severe    30     Norm
  M001   3/8/2003 11:30PM     40     Mild      20     Norm
  M002   7/10/2002 5:00PM    10    Moderate   48     Mild
  M002   10/10/2002 5:00PM    10      Norm     60     Moderate
  T101   11/11/2006 11:30PM   29      Norm     50     Moderate

已尝试的方法及问题

  • 使用pivot_longer:
    InterviewPivot<-CATMHData %>% pivot_longer(cols = c('Time_1','Time_2'...etc)names_to = 'InterviewNumber', values_to = 'IdNumber')
    
  • 使用melt:
    CATLong <- melt(CATMHData, id.vars = c("record_id"),measure.vars = c("anx_1","anx_2",etc.),variable.name= "Anxiety",value.name= "Score")
    

遇到的问题:

  • 报错提示无法合并“integer”和“character”类型;
  • 转换后结果不符合预期,出现重复行且格式混乱:
    recor…¹ subje…  time_1…³ cjanx_1 cjanx…⁴  cjdep_1 cjdep…⁶
         <int> <chr>   <chr>     <dbl> <chr>     <dbl>   <chr>  
      1       1 D001    12/12/2002…    80 Severe    30   Normal 
      2       1 D001    12/12/2002…    80 Severe    30   Normal 
    

解决方案

你之前的尝试错误在于未按变量类型分组转换,导致不同类型(数值/字符)被强行合并引发冲突。推荐用tidyr包的pivot_longer,通过正则匹配列名后缀实现精准分组转换:

步骤1:加载依赖包

library(tidyverse)

步骤2:执行宽转长操作

# 将示例数据存入变量
CATMHData <- structure(list(record_id = 1:6, subjectid = c("M001", "M002", 
"M003", "M004", "M005", "M006"), interviewid_1 = c(349976L, 351977L, 
NA, 349979L, 349980L, 349981L), endtime_1 = c("7/8/2021 17:02", 
"8/24/2021 16:48", "", "7/15/2021 16:32", "7/8/2021 16:06", "7/8/2021 15:09"
), cjanx_1 = c(33.83, 53.99, NA, 74.63, 38.85, 70.59), cjanx_cat_1 = c("Normal", 
"Moderate", "", "Severe", "Mild", "Severe"), cjanx_duration_1 = c(79.491, 
68.437, NA, 43.784, 145.51, 57.151), cjdep_1 = c(30.76, 62.59, 
NA, 75.91, 50.36, 62.59), cjdep_cat_1 = c("Normal", "Mild", "", 
"Severe", "Mild", "Mild"), cjdep_duration_1 = c(81.288, 63.692, 
NA, 81.121, 123.557, 61.212), cjss_1 = c(28.06, 50.88, NA, 59.62, 
37.77, 30.34)), row.names = c(NA, 6L), class = "data.frame")

# 执行转换
long_data <- CATMHData %>%
  # 保留不需要转换的ID列
  pivot_longer(
    cols = -c(record_id, subjectid),
    # 拆分列名为「变量名」和「访谈编号」,.value表示保留变量名作为新列名
    names_to = c(".value", "interview_num"),
    # 正则匹配:捕获「_」前的变量名和「_」后的数字编号
    names_pattern = "(.*)_(\\d+)"
  ) %>%
  # 重命名列以匹配期望格式
  rename(
    SubjID = subjectid,
    Time_1 = endtime_1,
    Anx = cjanx_1,
    Anx_Cat = cjanx_cat_1,
    Dep = cjdep_1,
    Dep_Cat = cjdep_cat_1
  ) %>%
  # 过滤空值或无效行(可选)
  filter(!is.na(Anx) & Time_1 != "") %>%
  # 选择需要的列
  select(SubjID, Time_1, Anx, Anx_Cat, Dep, Dep_Cat)

核心逻辑说明

  • names_pattern = "(.*)_(\\d+)":精准拆分你的列命名规则(如cjanx_1拆分为cjanx和1);
  • .value参数:自动将同前缀的列(同类型)转换为长格式中的同一列,彻底避免类型冲突;
  • 后续的rename和select是为了让输出完全匹配你期望的格式。

输出示例

print(long_data)

输出结果如下:

# A tibble: 5 × 6
  SubjID Time_1           Anx Anx_Cat  Dep Dep_Cat
  <chr>  <chr>          <dbl> <chr>  <dbl> <chr>  
1 M001   7/8/2021 17:02  33.8 Normal  30.8 Normal 
2 M002   8/24/2021 16:48  54.0 Moderate 62.6 Mild   
3 M004   7/15/2021 16:32  74.6 Severe  75.9 Severe 
4 M005   7/8/2021 16:06  38.8 Mild    50.4 Mild   
5 M006   7/8/2021 15:09  70.6 Severe  62.6 Mild   

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:45:34