当变量名称包含字符串信息时使用模式进行熔化 - 避免强制转换为数字
Melt using patterns when variable names contain string information - avoid coercion to numeric
我在 data.table::melt()
中使用 patterns()
参数来融合具有多个易于定义的模式的列的数据。它正在运行,但我没有看到如何创建字符索引变量而不是默认的数字细分。
例如,在数据集'A'中,狗和猫的列名有数字后缀(例如'dog_1'、'cat_2'),在[=14=中正确处理](查看生成的 'variable' 列):
A = data.table(idcol = c(1:5),
dog_1 = c(1:5), cat_1 = c(101:105),
dog_2 = c(6:10), cat_2 = c(106:110),
dog_3 = c(11:15), cat_3 = c(111:115))
head(melt(A, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat")))
idcol variable dog cat
1: 1 1 1 101
2: 2 1 2 102
3: 3 1 3 103
4: 4 1 4 104
5: 5 1 5 105
6: 1 2 6 106
然而,在数据集'B'中,狗和猫列的后缀是一个字符串(例如'dog_one'、'cat_two')。此类后缀在 melt
中转换为数字表示,请参阅“变量”列。
B = data.table(idcol = c(1:5),
dog_one = c(1:5), cat_one = c(101:105),
dog_two = c(6:10), cat_two = c(106:110),
dog_three = c(11:15), cat_three = c(111:115))
head(melt(B, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat")))
idcol variable dog cat
1: 1 1 1 101
2: 2 1 2 102
3: 3 1 3 103
4: 4 1 4 104
5: 5 1 5 105
6: 1 2 6 106
如何使用正确的字符串后缀 one/two/three 而不是 1/2/3 填充“变量”列?
从 data.table 1.14.1
(开发中;installation)开始,新功能 measure
可以更轻松地将具有串联变量名称的数据融合为所需格式(请参阅 ?measure
.
sep
arator 参数用于创建不同的 measure.vars
组。在 ...
参数中,我们进一步指定与 sep
.
生成的组对应的值的命运
在 OP 中,变量名称的格式为 species_number
,例如dog_one
。因此,我们需要 ...
中的两个符号来指定如何处理组 before 和 after sep
arator,一种用于物种(狗或猫),一种用于数量 (one-three)。
如果 ...
中的符号设置为 value.name
,则“melt
returns 多个 值列(带有由该组中的唯一值定义的名称)”。因此,因为您想要每个物种的多个列,分隔符定义的 first 组,...
中的 first 符号应该是value.name
.
second组,在分隔符之后,是数字,所以这里指定为...
中的第二个符号。我们想要数字的单个值列,因此在这里我们指定输出变量的所需列名,例如"nr".
melt(B, measure.vars = measure(value.name, nr, sep = "_"))
idcol nr dog cat
# 1: 1 one 1 101
# 2: 2 one 2 102
# 3: 3 one 3 103
# 4: 4 one 4 104
# 5: 5 one 5 105
# 6: 1 two 6 106
# 7: 2 two 7 107
# 8: 3 two 8 108
# 9: 4 two 9 109
# 10: 5 two 10 110
# 11: 1 three 11 111
# 12: 2 three 12 112
# 13: 3 three 13 113
# 14: 4 three 14 114
# 15: 5 three 15 115
前 data.table 1.14.1
可能有更简单的方法,但这似乎有效:
# grab suffixes of 'variable' names
suff <- unique(sub('^.*_', '', names(B[ , -1])))
# suff <- unique(tstrsplit(names(B[, -1]), "_")[[2]])
# melt
B2 <- melt(B, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat"))
# replace factor levels in 'variable' with the suffixes
setattr(B2$variable, "levels", suff)
B2
# idcol variable dog cat
# 1: 1 one 1 101
# 2: 2 one 2 102
# 3: 3 one 3 103
# 4: 4 one 4 104
# 5: 5 one 5 105
# 6: 1 two 6 106
# 7: 2 two 7 107
# 8: 3 two 8 108
# 9: 4 two 9 109
# 10: 5 two 10 110
# 11: 1 three 11 111
# 12: 2 three 12 112
# 13: 3 three 13 113
# 14: 4 three 14 114
# 15: 5 three 15 115
两个相关的 data.table
问题:
melt.data.table should offer variable
to match on the name, rather than the number
FR: expansion of melt functionality for handling names of output.
这是我认为 good'ol base::reshape
更清洁的(罕见)实例之一。它的 sep
参数在这里派上用场——'value' 列的名称和 'variable' 列的级别都是一次性生成的:
reshape(data = B,
varying = names(B[ , -1]),
sep = "_",
direction = "long")
我在 data.table::melt()
中使用 patterns()
参数来融合具有多个易于定义的模式的列的数据。它正在运行,但我没有看到如何创建字符索引变量而不是默认的数字细分。
例如,在数据集'A'中,狗和猫的列名有数字后缀(例如'dog_1'、'cat_2'),在[=14=中正确处理](查看生成的 'variable' 列):
A = data.table(idcol = c(1:5),
dog_1 = c(1:5), cat_1 = c(101:105),
dog_2 = c(6:10), cat_2 = c(106:110),
dog_3 = c(11:15), cat_3 = c(111:115))
head(melt(A, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat")))
idcol variable dog cat
1: 1 1 1 101
2: 2 1 2 102
3: 3 1 3 103
4: 4 1 4 104
5: 5 1 5 105
6: 1 2 6 106
然而,在数据集'B'中,狗和猫列的后缀是一个字符串(例如'dog_one'、'cat_two')。此类后缀在 melt
中转换为数字表示,请参阅“变量”列。
B = data.table(idcol = c(1:5),
dog_one = c(1:5), cat_one = c(101:105),
dog_two = c(6:10), cat_two = c(106:110),
dog_three = c(11:15), cat_three = c(111:115))
head(melt(B, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat")))
idcol variable dog cat
1: 1 1 1 101
2: 2 1 2 102
3: 3 1 3 103
4: 4 1 4 104
5: 5 1 5 105
6: 1 2 6 106
如何使用正确的字符串后缀 one/two/three 而不是 1/2/3 填充“变量”列?
从 data.table 1.14.1
(开发中;installation)开始,新功能 measure
可以更轻松地将具有串联变量名称的数据融合为所需格式(请参阅 ?measure
.
sep
arator 参数用于创建不同的 measure.vars
组。在 ...
参数中,我们进一步指定与 sep
.
在 OP 中,变量名称的格式为 species_number
,例如dog_one
。因此,我们需要 ...
中的两个符号来指定如何处理组 before 和 after sep
arator,一种用于物种(狗或猫),一种用于数量 (one-three)。
如果 ...
中的符号设置为 value.name
,则“melt
returns 多个 值列(带有由该组中的唯一值定义的名称)”。因此,因为您想要每个物种的多个列,分隔符定义的 first 组,...
中的 first 符号应该是value.name
.
second组,在分隔符之后,是数字,所以这里指定为...
中的第二个符号。我们想要数字的单个值列,因此在这里我们指定输出变量的所需列名,例如"nr".
melt(B, measure.vars = measure(value.name, nr, sep = "_"))
idcol nr dog cat
# 1: 1 one 1 101
# 2: 2 one 2 102
# 3: 3 one 3 103
# 4: 4 one 4 104
# 5: 5 one 5 105
# 6: 1 two 6 106
# 7: 2 two 7 107
# 8: 3 two 8 108
# 9: 4 two 9 109
# 10: 5 two 10 110
# 11: 1 three 11 111
# 12: 2 three 12 112
# 13: 3 three 13 113
# 14: 4 three 14 114
# 15: 5 three 15 115
前 data.table 1.14.1
可能有更简单的方法,但这似乎有效:
# grab suffixes of 'variable' names
suff <- unique(sub('^.*_', '', names(B[ , -1])))
# suff <- unique(tstrsplit(names(B[, -1]), "_")[[2]])
# melt
B2 <- melt(B, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat"))
# replace factor levels in 'variable' with the suffixes
setattr(B2$variable, "levels", suff)
B2
# idcol variable dog cat
# 1: 1 one 1 101
# 2: 2 one 2 102
# 3: 3 one 3 103
# 4: 4 one 4 104
# 5: 5 one 5 105
# 6: 1 two 6 106
# 7: 2 two 7 107
# 8: 3 two 8 108
# 9: 4 two 9 109
# 10: 5 two 10 110
# 11: 1 three 11 111
# 12: 2 three 12 112
# 13: 3 three 13 113
# 14: 4 three 14 114
# 15: 5 three 15 115
两个相关的 data.table
问题:
melt.data.table should offer variable
to match on the name, rather than the number
FR: expansion of melt functionality for handling names of output.
这是我认为 good'ol base::reshape
更清洁的(罕见)实例之一。它的 sep
参数在这里派上用场——'value' 列的名称和 'variable' 列的级别都是一次性生成的:
reshape(data = B,
varying = names(B[ , -1]),
sep = "_",
direction = "long")