R无法将列表写入JSON或YAML

xqnpmsa8  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(110)

我有一个很大的数据集,它来自survival包,我试图将其保存到磁盘:

> typeof(European204cad.prs.basic)
[1] "list"

我不想使用saveRDS,因为二进制输出只能由R读取。我想用Perl处理输出。
数据是coxph类,看起来像:

European204cad.prs.basic$coefficients       European204cad.prs.basic$nevent
European204cad.prs.basic$var                European204cad.prs.basic$terms
European204cad.prs.basic$loglik             European204cad.prs.basic$assign
European204cad.prs.basic$score              European204cad.prs.basic$wald.test
European204cad.prs.basic$iter               European204cad.prs.basic$concordance
European204cad.prs.basic$linear.predictors  European204cad.prs.basic$y
European204cad.prs.basic$residuals          European204cad.prs.basic$timefix
European204cad.prs.basic$means              European204cad.prs.basic$formula
European204cad.prs.basic$method             European204cad.prs.basic$call
European204cad.prs.basic$n

我使用过jsonliterlistrjson,但都无法将数据写入文件。
堇青石:

> z <- toJSON(European204cad.prs.basic)
Error: No method asJSON S3 class: coxph

列表:

> list.save(European204cad.prs.basic, file = 'tmp.json', type = 'JSON')
Error: No method asJSON S3 class: coxph
> list.save(European204cad.prs.basic, file = 'tmp.yaml', type = 'YAML')
Error in yaml::as.yaml(x, ...) : Unknown emitter error

以及从rjson

> z <- toJSON(European204cad.prs.basic)
Error in toJSON(European204cad.prs.basic) : 
  unable to convert R type 6 to JSON

如何将此列表保存到磁盘?

ldfqzlk8

ldfqzlk81#

既然你想在perl中处理,我推断你不想在模型中使用非数据类对象,我们可以过滤掉我们不想要的组件并将其写入json。
使用?coxph中的第一个示例:

library(survival)
test1 <- list(time=c(4,3,1,1,2,2,3), 
              status=c(1,1,1,0,1,1,0), 
              x=c(0,2,1,1,1,0,0), 
              sex=c(0,0,0,0,1,1,1)) 
mdl <- coxph(Surv(time, status) ~ x + strata(sex), test1)

我们可以看到mdl的每个组件是什么:

str(lapply(mdl, class))
# List of 20
#  $ coefficients     : chr "numeric"
#  $ var              : chr [1:2] "matrix" "array"
#  $ loglik           : chr "numeric"
#  $ score            : chr "numeric"
#  $ iter             : chr "integer"
#  $ linear.predictors: chr "numeric"
#  $ residuals        : chr "numeric"
#  $ means            : chr "numeric"
#  $ method           : chr "character"
#  $ n                : chr "integer"
#  $ nevent           : chr "numeric"
#  $ terms            : chr [1:2] "terms" "formula"
#  $ assign           : chr "list"
#  $ wald.test        : chr "numeric"
#  $ concordance      : chr "numeric"
#  $ y                : chr "Surv"
#  $ timefix          : chr "logical"
#  $ formula          : chr "formula"
#  $ xlevels          : chr "list"
#  $ call             : chr "call"

我们不需要formulacall这样的东西,我们可以接受其他的东西:

jsonlite::toJSON(Filter(function(z) !inherits(z, c("formula", "call")), mdl))
# Error: No method asJSON S3 class: Surv

好吧,这是一个你可能(?)想保留,我们将需要重新分类:

mdl$y
#  1  2  3  4  5  6  7 
#  4  3  1 1+  2  2 3+ 
dput(mdl$y)
# structure(c(4, 3, 1, 1, 2, 2, 3, 1, 1, 1, 0, 1, 1, 0), .Dim = c(7L, 
# 2L), .Dimnames = list(c("1", "2", "3", "4", "5", "6", "7"), c("time", 
# "status")), type = "right", class = "Surv")

在我看来像是矩阵......

as.matrix(mdl$y)
#   time status
# 1    4      1
# 2    3      1
# 3    1      1
# 4    1      0
# 5    2      1
# 6    2      1
# 7    3      0
mdl$y <- as.matrix(mdl$y)
jsonlite::toJSON(Filter(function(z) !inherits(z, c("formula", "call")), mdl))
# {"coefficients":[0.8023],"var":[[0.6763]],"loglik":[-3.8712,-3.3277],"score":[1.0509],"iter":[4],"linear.predictors":[-0.5731,1.0316,0.2292,0.2292,0.2292,-0.5731,-0.5731],"residuals":[-0.2631,-0.3094,0.7863,-0.2137,0.0463,0.5725,-0.6187],"means":[0.7143],"method":["efron"],"n":[7],"nevent":[5],"assign":{"x":[1]},"wald.test":[0.9518],"concordance":[3,1,2,1,0,0.6667,0.1667],"y":[[4,1],[3,1],[1,1],[1,0],[2,1],[2,1],[3,0]],"timefix":[true],"xlevels":{"strata(sex)":["sex=0","sex=1"]}}

请注意,mdl$y将丢失其名称。如果要保留矩阵的列名,请转换为框架:

mdl$y <- data.frame(as.matrix(mdl$y))
jsonlite::toJSON(Filter(function(z) !inherits(z, c("formula", "call")), mdl))
# {"coefficients":[0.8023],"var":[[0.6763]],"loglik":[-3.8712,-3.3277],"score":[1.0509],"iter":[4],"linear.predictors":[-0.5731,1.0316,0.2292,0.2292,0.2292,-0.5731,-0.5731],"residuals":[-0.2631,-0.3094,0.7863,-0.2137,0.0463,0.5725,-0.6187],"means":[0.7143],"method":["efron"],"n":[7],"nevent":[5],"assign":{"x":[1]},"wald.test":[0.9518],"concordance":[3,1,2,1,0,0.6667,0.1667],"y":[{"time":4,"status":1},{"time":3,"status":1},{"time":1,"status":1},{"time":1,"status":0},{"time":2,"status":1},{"time":2,"status":1},{"time":3,"status":0}],"timefix":[true],"xlevels":{"strata(sex)":["sex=0","sex=1"]}}

出于存档原因,如果要将公式 * 保留为字符串 *,可以使用以下命令之一(然后使用toJSON)。

## this
txt <- as.character(mdl$formula)
txt <- paste(c(txt[2], txt[-2]), collapse = " ")
mdl$formula <- txt
## or this, `paste`ing in case of multiline formulas
mdl$formula <- paste(capture.output(print(mdl$formula)), collapse = " ")

相关问题