将data.table(或data.frame)转换为yaml,然后恢复为原始格式

时间:2018-12-21 12:33:56

标签: r yaml

我想将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

1 个答案:

答案 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)