gpt4 book ai didi

r - 当变量名称包含字符串信息时使用模式融化 - 避免强制转换为数字

转载 作者:行者123 更新时间:2023-12-02 02:55:39 26 4
gpt4 key购买 nike

我使用 data.table::melt() 中的 patterns() 参数来融合包含多个易于定义模式的列的数据。它正在工作,但我不知道如何创建字符索引变量而不是默认的数字分割。

例如,在数据集“A”中,dog 和 cat 列名称具有数字后缀(例如“dog_1”、“cat_2”),这些后缀在 melt 中得到正确处理(请参阅生成的结果) “变量”列):

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 和 cat 列的后缀是字符串(例如“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

如何使用正确的字符串后缀一/二/三而不是 1/2/3 填充“变量”列?

最佳答案

data.table 1.14.1(正在开发中; installation )开始,新函数 measure 可以更轻松地将具有串联变量名称的数据融合为所需的格式(请参阅?measure

separator 参数用于创建不同组的measure.vars。在 ... 参数中,我们进一步指定与 sep 生成的组相对应的值的命运。

在 OP 中,变量名称的形式为 species_number,例如dog_one。因此,我们需要 ... 中的两个符号来指定separator 之前之后的分组方式处理,一种用于物种(狗或猫),另一种用于数量(一到三)。

如果...中的符号设置为value.name,则“melt返回多个值列(其名称由该组中的唯一值定义)”。因此,由于您希望每个物种有多个列,因此分隔符定义的 first 组、... 中的 first 符号应为 值.名称.

分隔符之后的第二组是数字,因此它被指定为...中的第二个符号。我们希望数字在单个值列中,因此在这里我们指定输出变量所需的列名称,例如“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 参数在这里派上用场 - “值”列的名称和“变量”列的级别都是一次性生成的:

reshape(data = B,
varying = names(B[ , -1]),
sep = "_",
direction = "long")

关于r - 当变量名称包含字符串信息时使用模式融化 - 避免强制转换为数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41883573/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com