How to convert fitdistrplus::fitdist summary into

2020-06-21 04:44发布

I have the following code:

x <- c(
  0.367141764080875, 0.250037975705769, 0.167204185003365, 0.299794433447383,
  0.366885973041269, 0.300453205296379, 0.333686861081341, 0.33301168850398,
  0.400142004893329, 0.399433677388411, 0.366077304765104, 0.166402979455671,
  0.466624230750293, 0.433499934139897, 0.300017278751768, 0.333673696762895,
  0.29973685692478
)

fn <- fitdistrplus::fitdist(x,"norm")
summary(fn)
#> Fitting of the distribution ' norm ' by maximum likelihood 
#> Parameters : 
#>        estimate Std. Error
#> mean 0.32846024 0.01918923
#> sd   0.07911922 0.01355908
#> Loglikelihood:  19.00364   AIC:  -34.00727   BIC:  -32.34084 
#> Correlation matrix:
#>      mean sd
#> mean    1  0
#> sd      0  1

Basically, it takes a vector and tried to fit the distribution using fitdistrplus package.

I tried looking at the broom package, but it doesn't have a function that covers that.

2条回答
兄弟一词,经得起流年.
2楼-- · 2020-06-21 05:14

Not sure exactly what you need, but you can try:

tidy_fn <- rbind(fn$estimate,fn$sd)

https://stats.stackexchange.com/questions/23539/use-fitdist-parameters-in-variables

查看更多
做自己的国王
3楼-- · 2020-06-21 05:17

When you call broom::tidy(fn) you receive an error that says:

Error: No tidy method for objects of class fitdist

This is because this function from broom only has a finite number objects that are "good to use", see methods(tidy) for the complete list. (Read more about S3 methods in R. More here).

So the function doesn't work for an object fitdist but works for a fitdistr object from MASS (more "famous").

We can then assign to fn that class, and then use broom:

class(fn) <- ("fitdist", "fitdistr") 
# notice that I've kept the original class and added the other
# you shouldn't overwrite classes. ie: don't to this: class(fn) <- "fitdistr"

broom::tidy(fn)
# # A tibble: 2 x 3
# term  estimate std.error
# <chr>    <dbl>     <dbl>
# 1 mean    0.328     0.0192
# 2 sd      0.0791    0.0136

Note that you can only see the parameters. If you wish to see more and organize everything as "tidy", you should tell us more about your expected output.

broom::tidy() gets you this far, if you want more I'd start by defining my own method function that works for a class fitdist object using as reference the tidy.fitdistr method, and adapting it.


Example of how I'd adapt from the original broom::tidy() code, using the S3 method for the class fitdist.

Define your own method (similar to how you define your own function):

# necessary libraries
library(dplyr)
library(broom)

# method definition:
tidy.fitdist <- function(x, ...) { # notice the use of .fitdist

  # you decide what you want to keep from summary(fn)
  # use fn$ecc... to see what you can harvest

  e1 <- tibble(
    term = names(x$estimate),
    estimate = unname(x$estimate),
    std.error = unname(x$sd)
  )

  e2 <- tibble(
    term = c("loglik", "aic", "bic"),
    value = c(unname(x$loglik), unname(x$aic), unname(x$bic))
  )

  e3 <- x$cor # I prefer this to: as_tibble(x$cor)

  list(e1, e2, e3) # you can name each element for a nicer result
  # example: list(params = e1, scores = e2, corrMatr = e3)
}

This is how you can call this new method now:

tidy(fn) # to be more clear this is calling your tidy.fitdist(fn) under the hood.
# [[1]]
# # A tibble: 2 x 3
# term  estimate std.error
# <chr>    <dbl>     <dbl>
# 1 mean    0.328     0.0192
# 2 sd      0.0791    0.0136
# 
# [[2]]
# # A tibble: 3 x 2
# term   value
# <chr>  <dbl>
# 1 loglik  19.0
# 2 aic    -34.0
# 3 bic    -32.3
# 
# [[3]]
#      mean sd
# mean    1  0
# sd      0  1

Notice that the class is:

class(fn)
[1] "fitdist"

So now you don't actually need to assign the fitdistr (from MASS) class as before.

查看更多
登录 后发表回答