如何用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
相关产品推荐
相关产品推荐

