Since you want to process in perl, I'm inferring that you don't want the non-data-like objects within a model. We can filter out the components we don't want and write that to json.
Using the first example from ?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)
We can see what each of the components of mdl
are:
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"
It should be clear that we don't want things like formula
and call
, we can just accept the others:
jsonlite::toJSON(Filter(function(z) !inherits(z, c("formula", "call")), mdl))
# Error: No method asJSON S3 class: Surv
Okay, that's one you might (?) want to keep that we will need to reclass:
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")
That looks like a matrix to me ...
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"]}}
Note that mdl$y
loses its names. If you want to preserve the column names of the matrix, convert to a frame instead:
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"]}}
For archiving reasons, if you want to preserve the formula as a string, you can do that with one of the following (and then 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 = " ")