我想将data.table(data.frame也这样做)转换为yaml格式,然后将该yaml转换回原始格式,但是不再有访问原始data.frame的权限。尝试过data.table()
,as.data.table()
(及其等效的data.frame)全部失败。
MWE:
library(data.table)
library(yaml)
foo <- rbindlist(list(
data.table(env = "default", a = "low", x = "A", z = "low", i = 1, j = 1, k = 1),
data.table(env = "default", a = "low", x = "A", z = "medium", i = 1, j = 2, k = 1),
data.table(env = "default", a = c("low", "medium", "high"), x = "A", z = "high", i = 2, j = 1, k = 1),
data.table(env = "other", a = c("low", "medium", "high"), x = "B", z = "na", i = 2, j = 2, k = 2)
))
out <- split(replace(foo, "env", NULL), foo$env)
out <- as.yaml(out)
# cat(out)
# foo is no longer available
# rm(foo)
bar <- yaml::yaml.load(out, as.named.list = T)
# how to make bar same as foo, i.e. as follows:
# env a x z i j k
# 1: default low A low 1 1 1
# 2: default low A medium 1 2 1
# 3: default low A high 2 1 1
# 4: default medium A high 2 1 1
# 5: default high A high 2 1 1
# 6: other low B na 2 2 2
# 7: other medium B na 2 2 2
# 8: other high B na 2 2 2
答案 0 :(得分:0)
问题是as.yaml
破坏了属性,这就是将data.frame与R
中的列表区分开的原因:
library(data.table)
library(yaml)
foo <- rbindlist(list(
data.table(env = "default", a = "low", x = "A", z = "low", i = 1, j = 1, k = 1),
data.table(env = "default", a = "low", x = "A", z = "medium", i = 1, j = 2, k = 1),
data.table(env = "default", a = c("low", "medium", "high"), x = "A", z = "high", i = 2, j = 1, k = 1),
data.table(env = "other", a = c("low", "medium", "high"), x = "B", z = "na", i = 2, j = 2, k = 2)
))
这就是属性的外观。
> attributes(foo)
$`names`
[1] "env" "a" "x" "z" "i" "j" "k"
$row.names
[1] 1 2 3 4 5 6 7 8
$class
[1] "data.table" "data.frame"
$.internal.selfref
<pointer: 0x0000000002521ef0>
这就是他们的样子。
foo2 <- as.yaml(foo)
# cat(out)
bar <- yaml::yaml.load(foo2)
> attributes(bar)
$`names`
[1] "env" "a" "x" "z" "i" "j" "k"
因此,向data.frame的转换非常简单:
attributes(bar)$class <- "data.frame"
attributes(bar)$row.names <- seq_along(bar[, 2])
或访问data.table:
attributes(bar)$class <- "data.frame"
bar <- as.data.table(bar)