熔化数组并使数值成为字符
Melt a array and make numeric values character
我有一个数组,我想根据 dimnames 融化它。问题是维度名称是大数值,因此将它们设为字符会将它们转换为错误的 ID,请参见示例:
test <- array(1:18, dim = c(3,3,2), dimnames = list(c(00901291282245454545454,329293929929292,2929992929922929),
c("a", "b", "c"),
c("d", "e")))
library(reshape2)
library(data.table)
test2 <- data.table(melt(test))
test2[, Var1 := as.character(Var1)]
> test2
Var1 Var2 Var3 value
1: 9.01291282245455e+20 a d 1
2: 329293929929292 a d 2
3: 2929992929922929 a d 3
4: 9.01291282245455e+20 b d 4
5: 329293929929292 b d 5
6: 2929992929922929 b d 6
7: 9.01291282245455e+20 c d 7
8: 329293929929292 c d 8
9: 2929992929922929 c d 9
10: 9.01291282245455e+20 a e 10
11: 329293929929292 a e 11
12: 2929992929922929 a e 12
13: 9.01291282245455e+20 b e 13
14: 329293929929292 b e 14
15: 2929992929922929 b e 15
16: 9.01291282245455e+20 c e 16
17: 329293929929292 c e 17
18: 2929992929922929 c e 18
如何使第一列具有大 ID 字符?我现在做的是给dimnames粘贴一个字符字母然后melt,变成一个字符再取一个子串,这样效率真的很低。重要的是它是一个有效的解决方案,因为数据集有数百万行。有两个问题,首先如果ID前面的0被删除,它被转换成一个e+20字符。
您需要将您的 dimnames 定义为 character
,然后稍微修改 melt.array
,当您在 array
上执行 melt
时会调用它:
test <- array(1:18, dim = c(3,3,2), dimnames = list(c("00901291282245454545454", "329293929929292", "2929992929922929"),
c("a", "b", "c"),
c("d", "e")))
自定义 melt.array
以添加一个参数,该参数允许您决定是否要转换:
melt.array2 <- function (data, varnames = names(dimnames(data)), conv=TRUE, ...)
{
values <- as.vector(data)
dn <- dimnames(data)
if (is.null(dn))
dn <- vector("list", length(dim(data)))
dn_missing <- sapply(dn, is.null)
dn[dn_missing] <- lapply(dim(data), function(x) 1:x)[dn_missing]
if(conv){ # conv is the new parameter to know if conversion needs to be done
char <- sapply(dn, is.character)
dn[char] <- lapply(dn[char], type.convert)
}
indices <- do.call(expand.grid, dn)
names(indices) <- varnames
data.frame(indices, value = values)
}
在您的示例中尝试新函数(conv=FALSE
):
head(melt.array2(test, conv=FALSE))
# X1 X2 X3 value
# 1 00901291282245454545454 a d 1
# 2 329293929929292 a d 2
# 3 2929992929922929 a d 3
# 4 00901291282245454545454 b d 4
# 5 329293929929292 b d 5
# 6 2929992929922929 b d 6
编辑
开发版reshape2
(devtools::install_github("hadley/reshape")
、melt.array
定义不同,可以使用参数as.is
避免转换:
melt(test, as.is=TRUE)
会得到与上面相同的结果(使用 Var1
等而不是 X1
等)。
我有一个数组,我想根据 dimnames 融化它。问题是维度名称是大数值,因此将它们设为字符会将它们转换为错误的 ID,请参见示例:
test <- array(1:18, dim = c(3,3,2), dimnames = list(c(00901291282245454545454,329293929929292,2929992929922929),
c("a", "b", "c"),
c("d", "e")))
library(reshape2)
library(data.table)
test2 <- data.table(melt(test))
test2[, Var1 := as.character(Var1)]
> test2
Var1 Var2 Var3 value
1: 9.01291282245455e+20 a d 1
2: 329293929929292 a d 2
3: 2929992929922929 a d 3
4: 9.01291282245455e+20 b d 4
5: 329293929929292 b d 5
6: 2929992929922929 b d 6
7: 9.01291282245455e+20 c d 7
8: 329293929929292 c d 8
9: 2929992929922929 c d 9
10: 9.01291282245455e+20 a e 10
11: 329293929929292 a e 11
12: 2929992929922929 a e 12
13: 9.01291282245455e+20 b e 13
14: 329293929929292 b e 14
15: 2929992929922929 b e 15
16: 9.01291282245455e+20 c e 16
17: 329293929929292 c e 17
18: 2929992929922929 c e 18
如何使第一列具有大 ID 字符?我现在做的是给dimnames粘贴一个字符字母然后melt,变成一个字符再取一个子串,这样效率真的很低。重要的是它是一个有效的解决方案,因为数据集有数百万行。有两个问题,首先如果ID前面的0被删除,它被转换成一个e+20字符。
您需要将您的 dimnames 定义为 character
,然后稍微修改 melt.array
,当您在 array
上执行 melt
时会调用它:
test <- array(1:18, dim = c(3,3,2), dimnames = list(c("00901291282245454545454", "329293929929292", "2929992929922929"),
c("a", "b", "c"),
c("d", "e")))
自定义 melt.array
以添加一个参数,该参数允许您决定是否要转换:
melt.array2 <- function (data, varnames = names(dimnames(data)), conv=TRUE, ...)
{
values <- as.vector(data)
dn <- dimnames(data)
if (is.null(dn))
dn <- vector("list", length(dim(data)))
dn_missing <- sapply(dn, is.null)
dn[dn_missing] <- lapply(dim(data), function(x) 1:x)[dn_missing]
if(conv){ # conv is the new parameter to know if conversion needs to be done
char <- sapply(dn, is.character)
dn[char] <- lapply(dn[char], type.convert)
}
indices <- do.call(expand.grid, dn)
names(indices) <- varnames
data.frame(indices, value = values)
}
在您的示例中尝试新函数(conv=FALSE
):
head(melt.array2(test, conv=FALSE))
# X1 X2 X3 value
# 1 00901291282245454545454 a d 1
# 2 329293929929292 a d 2
# 3 2929992929922929 a d 3
# 4 00901291282245454545454 b d 4
# 5 329293929929292 b d 5
# 6 2929992929922929 b d 6
编辑
开发版reshape2
(devtools::install_github("hadley/reshape")
、melt.array
定义不同,可以使用参数as.is
避免转换:
melt(test, as.is=TRUE)
会得到与上面相同的结果(使用 Var1
等而不是 X1
等)。