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

如何用R语言base包实现类似pivot_longer/melt的半宽数据转长格式?

用基础R的reshape()实现宽表转长表

我使用{tidyverse}和{data.table}已有多年,目前正在提升基础R语言技能。手里有一个半宽格式的数据框,包含两种蛋白在5个个体、两个时间点的蛋白浓度数据,目标是将其转换为含ID、Time、Protein、Concentration四列的长格式。使用tidyr/data.table/reshape2包的方案很简单,但我用base::reshape()始终无法得到理想结果。

示例数据

proteins <- data.frame(ID = rep(1:5, each = 2),
                       Time = rep(1:2, 5),
                       ProteinA = c(0.2, 3, 2.4, 5, 1.8, 2, 4.1, 1.7, 0.4, 3.0),
                       ProteinB = c(40, 27, 31, 67, 2, 19, 33, 26, 7, 21))

我的尝试(未生成Protein列)

reshape(proteins,
        direction = "long",
        varying = c("ProteinA", "ProteinB"),
        v.names = "Concentration")

其他包的可行方案

reshape2::melt()

reshape2::melt(proteins,
               id.vars = c("ID", "Time"),
               variable.name = "Protein",
               value.name = "Concentration")

tidyr::pivot_longer()

tidyr::pivot_longer(proteins,
                    cols = ProteinA:ProteinB,
                    names_to = "Protein",
                    values_to = "Concentration")

基础R reshape()的正确实现

要生成Protein列,需要补充timevar和times两个参数:

  • timevar:指定新生成的类别列名称(这里就是Protein)
  • times:指定该列的具体取值(对应原宽表中的ProteinA、ProteinB)

完整代码如下:

reshape(proteins,
        direction = "long",
        varying = c("ProteinA", "ProteinB"),
        v.names = "Concentration",
        timevar = "Protein",
        times = c("ProteinA", "ProteinB"))

如果需要重置自动生成的行名,可以再加一步:

long_df <- reshape(proteins,
                   direction = "long",
                   varying = c("ProteinA", "ProteinB"),
                   v.names = "Concentration",
                   timevar = "Protein",
                   times = c("ProteinA", "ProteinB"))
row.names(long_df) <- NULL

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 03:14:52