将 melt 与 data.table 一起使用仅适用于多个测量变量
Using melt with data.table only works with multiple measure variables
我对 data.table::melt()
的行为感到困惑。
我想将 data.table 从宽变长,
这是我的 data.table:
dt <- data.table(id=c(1,2,3), varA1=c(2,6,1), varA2=c(1,1,1),varA3=c(1,2,3),
varB1=c(1,0,1), varB2=c(1,1,1),varB3=c(0,0,0))
这是我想要的:
id index varA
1: 1 1 2
2: 2 1 6
3: 3 1 1
4: 1 2 1
5: 2 2 1
6: 3 2 1
7: 1 3 1
8: 2 3 2
9: 3 3 3
如果我同时包含 varA
和 varB
作为我的度量变量,它工作正常,使用:
dt_long <- melt(dt, id.vars = "id", measure=patterns("^varA","^varB"), value.name = c("varA","varB"),variable.name = "index")
输出符合预期:
id index varA varB
1: 1 1 2 1
2: 2 1 6 0
3: 3 1 1 1
4: 1 2 1 1
5: 2 2 1 1
6: 3 2 1 1
7: 1 3 1 0
8: 2 3 2 0
9: 3 3 3 0
不过,我只要varA
。只有一个测量变量,它不再有效。使用
dt_long <- melt(dt, id.vars ="id", measure=patterns("^varA"), value.name = "varA",variable.name = "index")
我得到:
id index varA
1: 1 varA1 2
2: 2 varA1 6
3: 3 varA1 1
4: 1 varA2 1
5: 2 varA2 1
6: 3 varA2 1
7: 1 varA3 1
8: 2 varA3 2
9: 3 varA3 3
为什么这里的 index
变量没有像以前那样列出 1,2,3?
在 melt
measure.vars
中使用多个列很棘手。
来自 melt
有关 measure.vars
的帮助:
multiple patterns will produce multiple columns
如果我们使用 "^varA","^varB"
将 data.table:::patterns
源代码应用到 dt
,我们得到:
cols <- colnames(dt)
p = unlist(list("^varA","^varB"), use.names = any(nzchar(list("^varA","^varB"))))
lapply(p, grep, cols)
[[1]]
[1] 2 3 4
[[2]]
[1] 5 6 7
导致:
VarA1
关联 VarB1
,因子指数 = 1
VarA2
关联 VarB2
,因子指数 = 2
VarA3
关联 VarB3
,因子指数 = 3
请注意,索引编号与 VarXi 索引无关,它只是 VarAi-VarBi
因子的自动编号。
例如,如果我们删除 VarA1
,我们会得到以下结果:
id index varA varB
1: 1 1 1 1
2: 2 1 1 0
3: 3 1 1 1
4: 1 2 1 1
5: 2 2 2 1
6: 3 2 3 1
7: 1 3 NA 0
8: 2 3 NA 0
9: 3 3 NA 0
VarA2
关联 VarB1
,因子指数 = 1
VarA3
与 VarB2
关联,因子指数 = 2
VarB3
单独,因子指数=3
在这两种情况下,由于这个因素是一个复合因素,data.table
returns 它的 numeric
索引。
只用一个pattern
时,直接得到一个levels
对应这个单pattern
的因子:
dt_long <- melt(dt, id.vars = "id", measure=patterns("^varA"), value.name = c("varA"),variable.name = "index")[]
dt_long$index
[1] varA1 varA1 varA1 varA2 varA2 varA2 varA3 varA3 varA3
Levels: varA1 varA2 varA3
您可以将其转换为 numeric
以获得预期结果:
dt_long[,index :=as.numeric(index)][]
id index varA
1: 1 1 2
2: 2 1 6
3: 3 1 1
4: 1 2 1
5: 2 2 1
6: 3 2 1
7: 1 3 1
8: 2 3 2
9: 3 3 3
我对 data.table::melt()
的行为感到困惑。
我想将 data.table 从宽变长,
这是我的 data.table:
dt <- data.table(id=c(1,2,3), varA1=c(2,6,1), varA2=c(1,1,1),varA3=c(1,2,3),
varB1=c(1,0,1), varB2=c(1,1,1),varB3=c(0,0,0))
这是我想要的:
id index varA
1: 1 1 2
2: 2 1 6
3: 3 1 1
4: 1 2 1
5: 2 2 1
6: 3 2 1
7: 1 3 1
8: 2 3 2
9: 3 3 3
如果我同时包含 varA
和 varB
作为我的度量变量,它工作正常,使用:
dt_long <- melt(dt, id.vars = "id", measure=patterns("^varA","^varB"), value.name = c("varA","varB"),variable.name = "index")
输出符合预期:
id index varA varB
1: 1 1 2 1
2: 2 1 6 0
3: 3 1 1 1
4: 1 2 1 1
5: 2 2 1 1
6: 3 2 1 1
7: 1 3 1 0
8: 2 3 2 0
9: 3 3 3 0
不过,我只要varA
。只有一个测量变量,它不再有效。使用
dt_long <- melt(dt, id.vars ="id", measure=patterns("^varA"), value.name = "varA",variable.name = "index")
我得到:
id index varA
1: 1 varA1 2
2: 2 varA1 6
3: 3 varA1 1
4: 1 varA2 1
5: 2 varA2 1
6: 3 varA2 1
7: 1 varA3 1
8: 2 varA3 2
9: 3 varA3 3
为什么这里的 index
变量没有像以前那样列出 1,2,3?
在 melt
measure.vars
中使用多个列很棘手。
来自 melt
有关 measure.vars
的帮助:
multiple patterns will produce multiple columns
如果我们使用 "^varA","^varB"
将 data.table:::patterns
源代码应用到 dt
,我们得到:
cols <- colnames(dt)
p = unlist(list("^varA","^varB"), use.names = any(nzchar(list("^varA","^varB"))))
lapply(p, grep, cols)
[[1]]
[1] 2 3 4
[[2]]
[1] 5 6 7
导致:
VarA1
关联VarB1
,因子指数 = 1VarA2
关联VarB2
,因子指数 = 2VarA3
关联VarB3
,因子指数 = 3
请注意,索引编号与 VarXi 索引无关,它只是 VarAi-VarBi
因子的自动编号。
例如,如果我们删除 VarA1
,我们会得到以下结果:
id index varA varB
1: 1 1 1 1
2: 2 1 1 0
3: 3 1 1 1
4: 1 2 1 1
5: 2 2 2 1
6: 3 2 3 1
7: 1 3 NA 0
8: 2 3 NA 0
9: 3 3 NA 0
VarA2
关联VarB1
,因子指数 = 1VarA3
与VarB2
关联,因子指数 = 2VarB3
单独,因子指数=3
在这两种情况下,由于这个因素是一个复合因素,data.table
returns 它的 numeric
索引。
只用一个pattern
时,直接得到一个levels
对应这个单pattern
的因子:
dt_long <- melt(dt, id.vars = "id", measure=patterns("^varA"), value.name = c("varA"),variable.name = "index")[]
dt_long$index
[1] varA1 varA1 varA1 varA2 varA2 varA2 varA3 varA3 varA3
Levels: varA1 varA2 varA3
您可以将其转换为 numeric
以获得预期结果:
dt_long[,index :=as.numeric(index)][]
id index varA
1: 1 1 2
2: 2 1 6
3: 3 1 1
4: 1 2 1
5: 2 2 1
6: 3 2 1
7: 1 3 1
8: 2 3 2
9: 3 3 3