将宽重塑为长,保留行名中的 ID 变量
Reshape wide to long, preserving ID variable from rownames
我正在尝试将以下数据转换为 R 中的长格式:
testdata <- data.frame(rnorm(10),rnorm(10),rnorm(10))
rownames(testdata) <- paste0("ID",1:10) # Ids
colnames(testdata) <- c(2001,2002,2003) # Years
testdata
所以列 = 时间,行 = ID。不应该太难,但在我发现的所有例子中都是相反的。如何在 datatable
或 reshape
或任何其他流行的数据框包中完成?
感谢您的任何提示。我知道一种方法是转置我的数据,但这似乎是一种相当低效的方法。
@Akron的有用回答:
reshape2::melt(as.matrix(testdata))
"But Why?"部分:
您的行名中包含重要信息,不是通常存储重要信息的好地方。我们重塑时需要这些信息。那么问题就变成了,如果我们输入矩阵而不是数据帧,为什么 melt
使用该信息?
原因是 melt
是一个通用函数,它根据您输入的数据类型分派一个方法(也称为更具体的函数)。所以如果m
是一个矩阵,你调用melt(m)
,那么R实际上是在执行melt.matrix(m)
。相反,如果 df
是一个数据帧并且你调用 melt(df)
,那么 R 实际上正在执行 melt.data.frame(df)
。这两个函数——melt.matrix()
和 melt.data.frame()
——处理行名的方式不同;方法 melt.matrix
以您想要的方式使用这些行名,而方法 melt.data.frame
则不然。因此,为了获得所需的输出,您需要将矩阵(而不是数据框)输入 melt
.
只是为了演示,如果我们将 ID 信息存储在 data.frame 的列中(如下面的 testdata2
中)而不是行名(如上面的 testdata
中) ,那么我们就可以将数据帧馈送到 melt
:
testdata2 <- data.frame(
ID = 1:10,
year2001 = rnorm(10),
year2002 = rnorm(10),
year2003 = rnorm(10) )
reshape2::melt(testdata2, "ID")
reshape2::melt(testdata2, id.vars="ID", measure.vars=2:4) #equivalently, but verbosely
你可以使用 tidyr 库
library(tidyr)
cbind(paste0("ID",1:10), gather(testdata, "years", "value"))
对我来说明显的黑客攻击似乎是将数据框的行名增加回常规列;那么你可以使用 reshape/reshape2/tidyr::gather
中的任何一个
> data.frame(ID=rownames(testdata), testdata, row.names=NULL)
ID X2001 X2002 X2003
1 ID1 0.6714540 1.1516917 0.51332801
2 ID2 -1.7309721 -1.8018835 1.54385452
3 ID3 -0.4831349 -1.3965915 -0.72819988
4 ID4 1.2591651 1.2436120 1.01472455
5 ID5 1.2346326 -1.4587475 -1.75097483
6 ID6 0.4279562 0.2595588 1.36560258
7 ID7 0.9990642 -1.0306002 -1.10165672
8 ID8 1.2118510 -0.3577358 -0.11696953
9 ID9 0.3074985 0.5177188 -0.09954961
10 ID10 -1.0418608 -1.8419336 -0.65401215
(请注意 "fixed" 您对 'X2001'、'X2002' 的非法同名...如果您真的想保留它们,请使用 ...check.names=FALSE)
)
只是为了将 变成一个完整的答案:
library(data.table)
melt(setDT(testdata, keep.rownames = TRUE), "rn")
rn variable value
1: ID1 2001 -0.25265860
2: ID2 2001 0.50538399
3: ID3 2001 0.68216394
4: ID4 2001 0.62203871
5: ID5 2001 0.59297019
6: ID6 2001 0.69383842
7: ID7 2001 1.77900432
8: ID8 2001 -1.69010623
9: ID9 2001 -2.17762905
10: ID10 2001 0.61463127
11: ID1 2002 0.42120060
12: ID2 2002 -0.16148732
...
我正在尝试将以下数据转换为 R 中的长格式:
testdata <- data.frame(rnorm(10),rnorm(10),rnorm(10))
rownames(testdata) <- paste0("ID",1:10) # Ids
colnames(testdata) <- c(2001,2002,2003) # Years
testdata
所以列 = 时间,行 = ID。不应该太难,但在我发现的所有例子中都是相反的。如何在 datatable
或 reshape
或任何其他流行的数据框包中完成?
感谢您的任何提示。我知道一种方法是转置我的数据,但这似乎是一种相当低效的方法。
@Akron的有用回答:
reshape2::melt(as.matrix(testdata))
"But Why?"部分:
您的行名中包含重要信息,不是通常存储重要信息的好地方。我们重塑时需要这些信息。那么问题就变成了,如果我们输入矩阵而不是数据帧,为什么 melt
使用该信息?
原因是 melt
是一个通用函数,它根据您输入的数据类型分派一个方法(也称为更具体的函数)。所以如果m
是一个矩阵,你调用melt(m)
,那么R实际上是在执行melt.matrix(m)
。相反,如果 df
是一个数据帧并且你调用 melt(df)
,那么 R 实际上正在执行 melt.data.frame(df)
。这两个函数——melt.matrix()
和 melt.data.frame()
——处理行名的方式不同;方法 melt.matrix
以您想要的方式使用这些行名,而方法 melt.data.frame
则不然。因此,为了获得所需的输出,您需要将矩阵(而不是数据框)输入 melt
.
只是为了演示,如果我们将 ID 信息存储在 data.frame 的列中(如下面的 testdata2
中)而不是行名(如上面的 testdata
中) ,那么我们就可以将数据帧馈送到 melt
:
testdata2 <- data.frame(
ID = 1:10,
year2001 = rnorm(10),
year2002 = rnorm(10),
year2003 = rnorm(10) )
reshape2::melt(testdata2, "ID")
reshape2::melt(testdata2, id.vars="ID", measure.vars=2:4) #equivalently, but verbosely
你可以使用 tidyr 库
library(tidyr)
cbind(paste0("ID",1:10), gather(testdata, "years", "value"))
对我来说明显的黑客攻击似乎是将数据框的行名增加回常规列;那么你可以使用 reshape/reshape2/tidyr::gather
> data.frame(ID=rownames(testdata), testdata, row.names=NULL)
ID X2001 X2002 X2003
1 ID1 0.6714540 1.1516917 0.51332801
2 ID2 -1.7309721 -1.8018835 1.54385452
3 ID3 -0.4831349 -1.3965915 -0.72819988
4 ID4 1.2591651 1.2436120 1.01472455
5 ID5 1.2346326 -1.4587475 -1.75097483
6 ID6 0.4279562 0.2595588 1.36560258
7 ID7 0.9990642 -1.0306002 -1.10165672
8 ID8 1.2118510 -0.3577358 -0.11696953
9 ID9 0.3074985 0.5177188 -0.09954961
10 ID10 -1.0418608 -1.8419336 -0.65401215
(请注意 "fixed" 您对 'X2001'、'X2002' 的非法同名...如果您真的想保留它们,请使用 ...check.names=FALSE)
)
只是为了将
library(data.table)
melt(setDT(testdata, keep.rownames = TRUE), "rn")
rn variable value 1: ID1 2001 -0.25265860 2: ID2 2001 0.50538399 3: ID3 2001 0.68216394 4: ID4 2001 0.62203871 5: ID5 2001 0.59297019 6: ID6 2001 0.69383842 7: ID7 2001 1.77900432 8: ID8 2001 -1.69010623 9: ID9 2001 -2.17762905 10: ID10 2001 0.61463127 11: ID1 2002 0.42120060 12: ID2 2002 -0.16148732 ...