用因子列融化 R data.table
Melting an R data.table with a factor column
我有以下 R data.table(尽管这也应该与 data.frame 一起缩放)。目标是重塑此 data.table 以绘制为 ggplot2
中的散点图。因此,我需要重塑此 data.table 以有一个 "factor" 列来为点着色:
> library(data.table)
> dt
ID x_A y_A x_B y_B
1: 05AC 0.81 3 0.92 2.05
2: 01BA 0.41 5 0.63 1.8
3: Z1AC 0.41 5 0.58 1.8
4: B2BA 0.21 6.5 1.00 1.8
....
我认为正确的输出应该是以下形式:
ID type x y
05AC A 0.81 3
05AC B 0.92 2.05
01BA A 0.41 5
01BA B 0.63 1.8
Z1AC A 0.41 5
Z1AC B 0.58 1.8
B2BA A 0.21 6.5
B2BA B 1.00 1.8
是否有以这种方式 "unfold" data.table 的标准方法?我很高兴在这种情况下如何使用 dplyr,但我怀疑应该有一个 data.table 方法。
melt()
会起作用,如果我能弄清楚如何创建列 type
,例如
melt(dt, id.vars=c("ID"))
只会根据一栏融化ID
我特别困惑 "scrapes" A 和 B 分别来自第 2-3 列和第 4-5 列...
dplyr
和 tidyr
的组合可以产生您想要的结果。由于缺少可重现的示例,因此未经测试。
library(tidyr)
library(dplyr)
dt %>%
gather(variable, value, -ID) %>%
separate(variable, c("group", "type"), sep = "\_") %>%
spread(group, value, na.rm = TRUE)
这是做什么的:
- 将除 ID 列以外的所有列收集到键值行、变量和值中。
- 将变量列分成组和类型,使用
_
作为分隔符。
- 将组行的内容分散到列中,并用值列填充它们,删除任何
NA
组合。
保持在 data.table
内,按照您建议的使用 melt
的方法,您可以 tstrsplit
根据“_”字符拆分变量。
## use tstrsplit to split a column on a regular expression
dt[, c("xy", "type") := tstrsplit(variable, "_")]
dt
# ID variable value xy type
# 1: 05AC x_A 0.81 x A
# 2: 01BA x_A 0.41 x A
# 3: Z1AC x_A 0.41 x A
# 4: B2BA x_A 0.21 x A
# 5: 05AC y_A 3.00 y A
# 6: 01BA y_A 5.00 y A
# 7: Z1AC y_A 5.00 y A
# 8: B2BA y_A 6.50 y A
# 9: 05AC x_B 0.92 x B
# 10: 01BA x_B 0.63 x B
# 11: Z1AC x_B 0.58 x B
# 12: B2BA x_B 1.00 x B
# 13: 05AC y_B 2.05 y B
# 14: 01BA y_B 1.80 y B
# 15: Z1AC y_B 1.80 y B
# 16: B2BA y_B 1.80 y B
这为您提供了所需解决方案的长格式。然后,您可以使用 dcast
加宽它
dcast(dt, formula = ID + type ~ xy)
# ID type x y
# 1: 01BA A 0.41 5.00
# 2: 01BA B 0.63 1.80
# 3: 05AC A 0.81 3.00
# 4: 05AC B 0.92 2.05
# 5: B2BA A 0.21 6.50
# 6: B2BA B 1.00 1.80
# 7: Z1AC A 0.41 5.00
# 8: Z1AC B 0.58 1.80
此答案的逻辑与 gather %>% separate %>% spread
的建议 dplyr
方法相同,但使用 data.table
。
我有以下 R data.table(尽管这也应该与 data.frame 一起缩放)。目标是重塑此 data.table 以绘制为 ggplot2
中的散点图。因此,我需要重塑此 data.table 以有一个 "factor" 列来为点着色:
> library(data.table)
> dt
ID x_A y_A x_B y_B
1: 05AC 0.81 3 0.92 2.05
2: 01BA 0.41 5 0.63 1.8
3: Z1AC 0.41 5 0.58 1.8
4: B2BA 0.21 6.5 1.00 1.8
....
我认为正确的输出应该是以下形式:
ID type x y
05AC A 0.81 3
05AC B 0.92 2.05
01BA A 0.41 5
01BA B 0.63 1.8
Z1AC A 0.41 5
Z1AC B 0.58 1.8
B2BA A 0.21 6.5
B2BA B 1.00 1.8
是否有以这种方式 "unfold" data.table 的标准方法?我很高兴在这种情况下如何使用 dplyr,但我怀疑应该有一个 data.table 方法。
melt()
会起作用,如果我能弄清楚如何创建列 type
,例如
melt(dt, id.vars=c("ID"))
只会根据一栏融化ID
我特别困惑 "scrapes" A 和 B 分别来自第 2-3 列和第 4-5 列...
dplyr
和 tidyr
的组合可以产生您想要的结果。由于缺少可重现的示例,因此未经测试。
library(tidyr)
library(dplyr)
dt %>%
gather(variable, value, -ID) %>%
separate(variable, c("group", "type"), sep = "\_") %>%
spread(group, value, na.rm = TRUE)
这是做什么的:
- 将除 ID 列以外的所有列收集到键值行、变量和值中。
- 将变量列分成组和类型,使用
_
作为分隔符。 - 将组行的内容分散到列中,并用值列填充它们,删除任何
NA
组合。
保持在 data.table
内,按照您建议的使用 melt
的方法,您可以 tstrsplit
根据“_”字符拆分变量。
## use tstrsplit to split a column on a regular expression
dt[, c("xy", "type") := tstrsplit(variable, "_")]
dt
# ID variable value xy type
# 1: 05AC x_A 0.81 x A
# 2: 01BA x_A 0.41 x A
# 3: Z1AC x_A 0.41 x A
# 4: B2BA x_A 0.21 x A
# 5: 05AC y_A 3.00 y A
# 6: 01BA y_A 5.00 y A
# 7: Z1AC y_A 5.00 y A
# 8: B2BA y_A 6.50 y A
# 9: 05AC x_B 0.92 x B
# 10: 01BA x_B 0.63 x B
# 11: Z1AC x_B 0.58 x B
# 12: B2BA x_B 1.00 x B
# 13: 05AC y_B 2.05 y B
# 14: 01BA y_B 1.80 y B
# 15: Z1AC y_B 1.80 y B
# 16: B2BA y_B 1.80 y B
这为您提供了所需解决方案的长格式。然后,您可以使用 dcast
加宽它
dcast(dt, formula = ID + type ~ xy)
# ID type x y
# 1: 01BA A 0.41 5.00
# 2: 01BA B 0.63 1.80
# 3: 05AC A 0.81 3.00
# 4: 05AC B 0.92 2.05
# 5: B2BA A 0.21 6.50
# 6: B2BA B 1.00 1.80
# 7: Z1AC A 0.41 5.00
# 8: Z1AC B 0.58 1.80
此答案的逻辑与 gather %>% separate %>% spread
的建议 dplyr
方法相同,但使用 data.table
。