将summary.lm转换为JSON

时间:2018-11-16 21:25:23

标签: r jsonlite plumber

我正在R中用水管工运行R脚本。我试图从R脚本取回JSON响应。但是似乎下面的语句输出不支持JSON响应。

summary(fm1 <- lm(log(dist) ~ log(speed), data = cars))

我得到以上陈述的以下内容。

Call:
lm(formula = log(dist) ~ log(speed), data = cars)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.00215 -0.24578 -0.02898  0.20717  0.88289 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -0.7297     0.3758  -1.941   0.0581 .  
log(speed)    1.6024     0.1395  11.484 2.26e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.4053 on 48 degrees of freedom
Multiple R-squared:  0.7331,    Adjusted R-squared:  0.7276 
F-statistic: 131.9 on 1 and 48 DF,  p-value: 2.259e-15

我尝试使用jsonlite :: toJSON,但是我想我在某处缺少R的基本原理。

我应该怎么做才能将输出转换为JSON结构?

1 个答案:

答案 0 :(得分:2)

Since you did not provide data:

ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2, 10, 20, labels = c("Ctl","Trt"))
weight <- c(ctl, trt)
lm.D9 <- lm(weight ~ group)

s <- summary(lm.D9)

This is what ^^ looks like:

str(s)
## List of 11
##  $ call         : language lm(formula = weight ~ group)
##  $ terms        :Classes 'terms', 'formula'  language weight ~ group
##   .. ..- attr(*, "variables")= language list(weight, group)
##   .. ..- attr(*, "factors")= int [1:2, 1] 0 1
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:2] "weight" "group"
##   .. .. .. ..$ : chr "group"
##   .. ..- attr(*, "term.labels")= chr "group"
##   .. ..- attr(*, "order")= int 1
##   .. ..- attr(*, "intercept")= int 1
##   .. ..- attr(*, "response")= int 1
##   .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
##   .. ..- attr(*, "predvars")= language list(weight, group)
##   .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "factor"
##   .. .. ..- attr(*, "names")= chr [1:2] "weight" "group"
##  $ residuals    : Named num [1:20] -0.862 0.548 0.148 1.078 -0.532 ...
##   ..- attr(*, "names")= chr [1:20] "1" "2" "3" "4" ...
##  $ coefficients : num [1:2, 1:4] 5.032 -0.371 0.22 0.311 22.85 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:2] "(Intercept)" "groupTrt"
##   .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
##  $ aliased      : Named logi [1:2] FALSE FALSE
##   ..- attr(*, "names")= chr [1:2] "(Intercept)" "groupTrt"
##  $ sigma        : num 0.696
##  $ df           : int [1:3] 2 18 2
##  $ r.squared    : num 0.0731
##  $ adj.r.squared: num 0.0216
##  $ fstatistic   : Named num [1:3] 1.42 1 18
##   ..- attr(*, "names")= chr [1:3] "value" "numdf" "dendf"
##  $ cov.unscaled : num [1:2, 1:2] 0.1 -0.1 -0.1 0.2
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:2] "(Intercept)" "groupTrt"
##   .. ..$ : chr [1:2] "(Intercept)" "groupTrt"
##  - attr(*, "class")= chr "summary.lm"

We can totally turn arbitrary objects to JSON if you don't mind a potential (in this case definite) loss in element resolution (you are likely fine at R fundamentals…you are lacking in reading docs tho ):

jsonlite::toJSON(s, force=TRUE, pretty=TRUE)
## {
##   "call": {},
##   "terms": {},
##   "residuals": [-0.862, 0.548, 0.148, 1.078, -0.532, -0.422, 0.138, -0.502, 0.298, 0.108, 0.149, -0.491, -0.251, -1.071, 1.209, -0.831, 1.369, 0.229, -0.341, 0.029],
##   "coefficients": [
##     [5.032, 0.2202, 22.8501, 9.5471e-15],
##     [-0.371, 0.3114, -1.1913, 0.249]
##   ],
##   "aliased": [false, false],
##   "sigma": [0.6964],
##   "df": [2, 18, 2],
##   "r.squared": [0.0731],
##   "adj.r.squared": [0.0216],
##   "fstatistic": [1.4191, 1, 18],
##   "cov.unscaled": [
##     [0.1, -0.1],
##     [-0.1, 0.2]
##   ]
## } 

If you want the missing values you'll need to convert them appropriately before doing the toJSON()

Further, this is what base:::print.summary.lm does so you could also adopt it and make your own JSON:

function (x, digits = max(3L, getOption("digits") - 3L), symbolic.cor = x$symbolic.cor, signif.stars = getOption("show.signif.stars"), ...) {
    cat("\nCall:\n", paste(deparse(x$call), sep = "\n", collapse = "\n"), 
        "\n\n", sep = "")
    resid <- x$residuals
    df <- x$df
    rdf <- df[2L]
    cat(if (!is.null(x$weights) && diff(range(x$weights))) 
        "Weighted ", "Residuals:\n", sep = "")
    if (rdf > 5L) {
        nam <- c("Min", "1Q", "Median", "3Q", "Max")
        rq <- if (length(dim(resid)) == 2L) 
            structure(apply(t(resid), 1L, quantile), dimnames = list(nam, 
                dimnames(resid)[[2L]]))
        else {
            zz <- zapsmall(quantile(resid), digits + 1L)
            structure(zz, names = nam)
        }
        print(rq, digits = digits, ...)
    }
    else if (rdf > 0L) {
        print(resid, digits = digits, ...)
    }
    else {
        cat("ALL", df[1L], "residuals are 0: no residual degrees of freedom!")
        cat("\n")
    }
    if (length(x$aliased) == 0L) {
        cat("\nNo Coefficients\n")
    }
    else {
        if (nsingular <- df[3L] - df[1L]) 
            cat("\nCoefficients: (", nsingular, " not defined because of singularities)\n", 
                sep = "")
        else cat("\nCoefficients:\n")
        coefs <- x$coefficients
        if (any(aliased <- x$aliased)) {
            cn <- names(aliased)
            coefs <- matrix(NA, length(aliased), 4, dimnames = list(cn, 
                colnames(coefs)))
            coefs[!aliased, ] <- x$coefficients
        }
        printCoefmat(coefs, digits = digits, signif.stars = signif.stars, 
            na.print = "NA", ...)
    }
    cat("\nResidual standard error:", format(signif(x$sigma, 
        digits)), "on", rdf, "degrees of freedom")
    cat("\n")
    if (nzchar(mess <- naprint(x$na.action))) 
        cat("  (", mess, ")\n", sep = "")
    if (!is.null(x$fstatistic)) {
        cat("Multiple R-squared: ", formatC(x$r.squared, digits = digits))
        cat(",\tAdjusted R-squared: ", formatC(x$adj.r.squared, 
            digits = digits), "\nF-statistic:", formatC(x$fstatistic[1L], 
            digits = digits), "on", x$fstatistic[2L], "and", 
            x$fstatistic[3L], "DF,  p-value:", format.pval(pf(x$fstatistic[1L], 
                x$fstatistic[2L], x$fstatistic[3L], lower.tail = FALSE), 
                digits = digits))
        cat("\n")
    }
    correl <- x$correlation
    if (!is.null(correl)) {
        p <- NCOL(correl)
        if (p > 1L) {
            cat("\nCorrelation of Coefficients:\n")
            if (is.logical(symbolic.cor) && symbolic.cor) {
                print(symnum(correl, abbr.colnames = NULL))
            }
            else {
                correl <- format(round(correl, 2), nsmall = 2, 
                  digits = digits)
                correl[!lower.tri(correl)] <- ""
                print(correl[-1, -p, drop = FALSE], quote = FALSE)
            }
        }
    }
    cat("\n")
    invisible(x)
}