performance of rho2hat and ppm in spatstat - ppm

I want to compare the performance of nonparametric intensity function estimator "rho2hat" with "ppm".
My question how can I perform a test to see estimation works better? I couldn't use quadrat.test?

As mentioned in the comment by #adrian-baddeley your suggested strategy
will just measure the difference between two results. The way you can
calculate the expected number of points in different regions from an
estimated intensity is as follows:
library(spatstat)
#> Loading required package: nlme
#> Loading required package: rpart
#>
#> spatstat 1.51-0.035 (nickname: 'Spatfefe')
#> For an introduction to spatstat, type 'beginner'
elev <- bei.extra$elev
grad <- bei.extra$grad
non <- rho2hat(bei, elev, grad)
pred <- predict(non)
grid <- quadrats(pred, nx = 4, ny = 2)
by(pred, grid, integral)
#> 1:
#> [1] 522.0247
#>
#> 2:
#> [1] 503.6255
#>
#> 3:
#> [1] 344.8552
#>
#> 4:
#> [1] 522.834
#>
#> 5:
#> [1] 454.5958
#>
#> 6:
#> [1] 470.2484
#>
#> 7:
#> [1] 556.1989
#>
#> 8:
#> [1] 415.8889

Related

R use the name of function as a parameter in formals

I am working with several classification algorithms from different libraries (for example):
library(ranger) #RandomForest
library(gbm) #Gradient Boosting
I need to use formals function to get all the arguments from all of them.
The following attempts works perfectly:
formals(gbm)
formals(gbm::gbm)
formals("gbm")
functionName="gbm"
formals(functionName)
What I need is to parametrize the name of the package as well as the name of the function, but it fails. Something like this:
> packageName="gbm"
> functionName="gbm"
> formals(packageName::functionName)
Error in loadNamespace(x) : there is no package called ‘packageName’
Is there anyway to do it?
Thanks
The good thing is that :: accepts strings:
`::`("gbm", "gbm")
The above code is working.
However, when we use an object name in which the string is stored, :: takes this as literal expression and looks for a package called packageName.
packageName <- functionName <- "gbm"
`::`(packageName, functionName)
#> Error in loadNamespace(x): there is no package called 'packageName'
With base R we can use eval(bquote()) and evaluate the strings early with .().
By evaluating the strings early with .() we make it clear that we are really looking for the string value (that is the value of packageName) and not the object name itself.
formals(eval(bquote(`::`(.(packageName), .(functionName)))))
#> $formula
#> formula(data)
#>
#> $distribution
#> [1] "bernoulli"
#>
#> $data
#> list()
#>
#> $weights
#>
#>
#> $var.monotone
#> NULL
#>
#> $n.trees
#> [1] 100
#>
#> $interaction.depth
#> [1] 1
#>
#> $n.minobsinnode
#> [1] 10
#>
#> $shrinkage
#> [1] 0.1
#>
#> $bag.fraction
#> [1] 0.5
#>
#> $train.fraction
#> [1] 1
#>
#> $cv.folds
#> [1] 0
#>
#> $keep.data
#> [1] TRUE
#>
#> $verbose
#> [1] FALSE
#>
#> $class.stratify.cv
#> NULL
#>
#> $n.cores
#> NULL
With {rlang} we can use inject() and !! sym():
library(rlang)
formals(inject(`::`(!! sym(packageName), !! sym(functionName))))
Of course in base R we always have the option to eval(parse()):
packageName="gbm"
functionName="gbm"
formals(eval(str2lang(paste0(packageName, "::", functionName))))
Created on 2023-02-19 with reprex v2.0.2

How do I extract the classification tree from this parsnip model in R?

I am working through 'Machine Learning & R Expert techniques for predictive modeling' by Brett Lantz. I am using the tidymodels suite as I try the example modeling exercises in R.
I am working through chapter 5 in which you build a decision tree with the C5.0 algorithm. I hav e created the model using the code shown below
c5_v1 <- C5_rules() %>%
set_mode('classification') %>%
set_engine('C5.0')
c5_res_1 <- fit(object = c5_v1, formula = default ~., data = credit_train)
This has worked successfully:
parsnip model object
Call:
C5.0.default(x = x, y = y, trials = trials, rules = TRUE, control
= C50::C5.0Control(minCases = minCases, seed = sample.int(10^5, 1), earlyStopping
= FALSE))
Rule-Based Model
Number of samples: 900
Number of predictors: 20
Number of Rules: 22
Non-standard options: attempt to group attributes
Try as I might, Google as I do, read parsnips documentation, etc., I cannot find out how to view the decision tree. Can anyone tell me how to view the actual tree it has created?
Do note C5_rules() is a specification for a rule-fit model. Therefore, after fitting with C5_rules(), you shouldn't expect the output to be a decision tree but a set of rules instead.
With the C5.0 engine, you're able to get both a decision tree output and a rules output. With the fitted model, run extract_fit_engine() to obtain the engine specific fit embedded within a parsnip model fit, followed by summary() to extract the output.
library(tidymodels)
library(rules)
#>
#> Attaching package: 'rules'
#> The following object is masked from 'package:dials':
#>
#> max_rules
data(penguins, package = "modeldata")
#model specification
C5_decision_tree <- decision_tree() |>
set_engine("C5.0") |>
set_mode("classification")
C5_rules <- C5_rules() |>
#no need to set engine because only C5.0 is used for C5_rules()
#verify with show_engines("C5_rules")
set_mode("classification")
#fitting the models
C5_decision_tree_fitted <- C5_decision_tree |>
fit(species ~ ., data = penguins)
C5_rules_fitted <- C5_rules |>
fit(species ~ ., data = penguins)
#extracting decision tree
C5_decision_tree_fitted |>
extract_fit_engine() |>
summary()
#>
#> Call:
#> C5.0.default(x = x, y = y, trials = 1, control = C50::C5.0Control(minCases =
#> 2, sample = 0))
#>
#>
#> C5.0 [Release 2.07 GPL Edition] Mon Jul 4 09:32:16 2022
#> -------------------------------
#>
#> Class specified by attribute `outcome'
#>
#> Read 333 cases (7 attributes) from undefined.data
#>
#> Decision tree:
#>
#> flipper_length_mm > 206:
#> :...island = Biscoe: Gentoo (118)
#> : island in {Dream,Torgersen}:
#> : :...bill_length_mm <= 46.5: Adelie (2)
#> : bill_length_mm > 46.5: Chinstrap (5)
#> flipper_length_mm <= 206:
#> :...bill_length_mm > 43.3:
#> :...island in {Biscoe,Torgersen}: Adelie (4/1)
#> : island = Dream: Chinstrap (59/1)
#> bill_length_mm <= 43.3:
#> :...bill_length_mm <= 42.3: Adelie (134/1)
#> bill_length_mm > 42.3:
#> :...sex = female: Chinstrap (4)
#> sex = male: Adelie (7)
#>
#>
#> Evaluation on training data (333 cases):
#>
#> Decision Tree
#> ----------------
#> Size Errors
#>
#> 8 3( 0.9%) <<
#>
#>
#> (a) (b) (c) <-classified as
#> ---- ---- ----
#> 145 1 (a): class Adelie
#> 1 67 (b): class Chinstrap
#> 1 118 (c): class Gentoo
#>
#>
#> Attribute usage:
#>
#> 100.00% flipper_length_mm
#> 64.56% bill_length_mm
#> 56.46% island
#> 3.30% sex
#>
#>
#> Time: 0.0 secs
#extracting rules
C5_rules_fitted |>
extract_fit_engine() |>
summary()
#>
#> Call:
#> C5.0.default(x = x, y = y, trials = trials, rules = TRUE, control
#> = C50::C5.0Control(minCases = minCases, seed = sample.int(10^5,
#> 1), earlyStopping = FALSE))
#>
#>
#> C5.0 [Release 2.07 GPL Edition] Mon Jul 4 09:32:16 2022
#> -------------------------------
#>
#> Class specified by attribute `outcome'
#>
#> Read 333 cases (7 attributes) from undefined.data
#>
#> Rules:
#>
#> Rule 1: (68, lift 2.2)
#> bill_length_mm <= 43.3
#> sex = male
#> -> class Adelie [0.986]
#>
#> Rule 2: (208/64, lift 1.6)
#> flipper_length_mm <= 206
#> -> class Adelie [0.690]
#>
#> Rule 3: (48, lift 4.8)
#> island = Dream
#> bill_length_mm > 46.5
#> -> class Chinstrap [0.980]
#>
#> Rule 4: (34/1, lift 4.6)
#> bill_length_mm > 42.3
#> flipper_length_mm <= 206
#> sex = female
#> -> class Chinstrap [0.944]
#>
#> Rule 5: (118, lift 2.8)
#> island = Biscoe
#> flipper_length_mm > 206
#> -> class Gentoo [0.992]
#>
#> Default class: Adelie
#>
#>
#> Evaluation on training data (333 cases):
#>
#> Rules
#> ----------------
#> No Errors
#>
#> 5 2( 0.6%) <<
#>
#>
#> (a) (b) (c) <-classified as
#> ---- ---- ----
#> 146 (a): class Adelie
#> 1 67 (b): class Chinstrap
#> 1 118 (c): class Gentoo
#>
#>
#> Attribute usage:
#>
#> 97.90% flipper_length_mm
#> 49.85% island
#> 40.84% bill_length_mm
#> 30.63% sex
#>
#>
#> Time: 0.0 secs
Created on 2022-07-04 by the reprex package (v2.0.1)

What does a tidymodels survival fit require more than one predictor

Can a survival model with just the treatment as a predictor be fit
with a tidymodels survival function?
Here I mention the example, which uses many predictors, then try
to duplicated it with only one predictor. This fails.
https://www.tidyverse.org/blog/2021/11/survival-analysis-parsnip-adjacent/
has code to fit a survival tidymodel
library(survival)
bladder_train <- bladder[-c(1:3),]
bladder_test <- bladder[1:3,]
cox_spec <- proportional_hazards(penalty = 0.123) %>%
set_engine("glmnet")
f_fit <- fit(cox_spec,
Surv(stop, event) ~ rx + size + number + strata(enum),
data = bladder_train)
But with only the treatment in the model, it does not work
f_fit <- fit(cox_spec,
Surv(stop, event) ~ rx,
data = bladder_train)
Why? What am I missing
It seems the error has more to do with glmnet than tidymodels. This is the error:
library(survival)
library(censored)
#> Loading required package: parsnip
library(tidymodels)
#> Registered S3 method overwritten by 'tune':
#> method from
#> required_pkgs.model_spec parsnip
bladder_train <- bladder[-c(1:3), ]
bladder_test <- bladder[1:3, ]
cox_spec <- proportional_hazards(penalty = 0.123) %>%
set_engine("glmnet")
f_fit <- fit(cox_spec,
Surv(stop, event) ~ rx,
data = bladder_train)
#> Error in glmnet::glmnet(data_obj$x, data_obj$y, family = "cox", alpha = alpha, : x should be a matrix with 2 or more columns
Created on 2021-12-30 by the reprex package (v2.0.1)
glmnet needs a mtrix with 2 or more columns. Using just rx means you'd have just one column. If I add size as an additional feature, it works just fine.
library(survival)
library(censored)
#> Loading required package: parsnip
library(tidymodels)
#> Registered S3 method overwritten by 'tune':
#> method from
#> required_pkgs.model_spec parsnip
bladder_train <- bladder[-c(1:3), ]
bladder_test <- bladder[1:3, ]
cox_spec <- proportional_hazards(penalty = 0.123) %>%
set_engine("glmnet")
f_fit <- fit(cox_spec,
Surv(stop, event) ~ rx + size,
data = bladder_train)
f_fit
#> parsnip model object
#>
#> Fit time: NA
#>
#> Call: glmnet::glmnet(x = data_obj$x, y = data_obj$y, family = "cox", alpha = alpha, lambda = lambda)
#>
#> Df %Dev Lambda
#> 1 0 0.00 0.070850
#> 2 1 0.10 0.064560
#> 3 1 0.18 0.058820
#> 4 1 0.24 0.053600
#> 5 1 0.30 0.048840
#> 6 2 0.35 0.044500
#> 7 2 0.43 0.040550
#> 8 2 0.50 0.036940
#> 9 2 0.55 0.033660
#> 10 2 0.60 0.030670
#> 11 2 0.64 0.027950
#> 12 2 0.67 0.025460
#> 13 2 0.70 0.023200
#> 14 2 0.72 0.021140
#> 15 2 0.74 0.019260
#> 16 2 0.75 0.017550
#> 17 2 0.77 0.015990
#> 18 2 0.78 0.014570
#> 19 2 0.79 0.013280
#> 20 2 0.79 0.012100
#> 21 2 0.80 0.011020
#> 22 2 0.81 0.010040
#> 23 2 0.81 0.009151
#> 24 2 0.81 0.008338
#> 25 2 0.82 0.007597
#> 26 2 0.82 0.006922
#> 27 2 0.82 0.006308
#> 28 2 0.82 0.005747
#> 29 2 0.82 0.005237
#> 30 2 0.83 0.004771
#> 31 2 0.83 0.004348
#> 32 2 0.83 0.003961
#> 33 2 0.83 0.003609
#> 34 2 0.83 0.003289
#> 35 2 0.83 0.002997
#> 36 2 0.83 0.002730
#> 37 2 0.83 0.002488
#> 38 2 0.83 0.002267
#> 39 2 0.83 0.002065
#> 40 2 0.83 0.001882
#> 41 2 0.83 0.001715
#> The training data has been saved for prediction.
Created on 2021-12-30 by the reprex package (v2.0.1)
If you wanted to just use one feature rx, consider other models e.g. decision trees
library(survival)
library(censored)
#> Loading required package: parsnip
library(tidymodels)
#> Registered S3 method overwritten by 'tune':
#> method from
#> required_pkgs.model_spec parsnip
bladder_train <- bladder[-c(1:3), ]
bladder_test <- bladder[1:3, ]
dt_spec <- decision_tree() %>%
set_engine("rpart") %>%
set_mode("censored regression")
f_fit <- fit(dt_spec,
Surv(stop, event) ~ rx,
data = bladder_train)
f_fit
#> parsnip model object
#>
#> $rpart
#> n= 337
#>
#> node), split, n, deviance, yval
#> * denotes terminal node
#>
#> 1) root 337 403.0968 1.0000000
#> 2) rx>=1.5 152 166.6335 0.7751669 *
#> 3) rx< 1.5 185 231.2927 1.1946030 *
#>
#> $survfit
#>
#> Call: prodlim::prodlim(formula = form, data = data)
#> Stratified Kaplan-Meier estimator for the conditional event time survival function
#> Discrete predictor variable: rpartFactor (0.775166899958249, 1.19460305107131)
#>
#> $levels
#> [1] "0.775166899958249" "1.19460305107131"
#>
#> attr(,"class")
#> [1] "pecRpart"
Created on 2021-12-30 by the reprex package (v2.0.1)

Compute marginal effects of slope in mixed model with interactions (between categorical and metric covariates)

I currently work on a mixed model, that includes multiple interactions of a categorical variable and a metric cost variable to predict a metric output. I'm very interested in the changes of the linear relationship between cost and output (slope) due to the numerous categorical variables.
Because I have multiple categorical covariates that interact with the cost (and there are also random effects) I look for a straightforward method to compute the marginal effects of these slopes. I'm not looking for a prediction or expectation of the output, but would rather like to see the "marginal slope" instead.
I've included some example code below
library(housingData)
library(tidyverse)
library(lme4)
#> Loading required package: Matrix
#>
#> Attaching package: 'Matrix'
#> The following objects are masked from 'package:tidyr':
#>
#> expand, pack, unpack
set.seed(12345)
df <- housing %>%
filter(complete.cases(.)) %>%
mutate(house_type = factor(sample(c("A", "B", "C"), nrow(.), replace = TRUE)),
timeperiod = as.factor(if_else(lubridate::year(time) < 2012,
"before_2012",
"2012_and_after")))
# model categorical effects on slope, after main effect has been fitted
lm1 <- lm(medSoldPriceSqft ~ 0 + medListPriceSqft, data = df)
coef(lm1)
#> medListPriceSqft
#> 0.9137324
df2 <- df %>%
modelr::add_residuals(lm1, "medSoldPriceSqft_after_list_price")
mod2 <- lmer(medSoldPriceSqft_after_list_price ~ 0 + medListPriceSqft:house_type
+ medListPriceSqft:timeperiod +
(0 + medListPriceSqft:house_type + medListPriceSqft:timeperiod| state), data = df2)
fixef(mod2)
#> medListPriceSqft:house_typeA medListPriceSqft:house_typeB
#> 0.02819789 0.01725657
#> medListPriceSqft:house_typeC medListPriceSqft:timeperiodbefore_2012
#> 0.01733967 0.01526881
ranef(mod2)$state
#> medListPriceSqft:house_typeA medListPriceSqft:house_typeB
#> AL -0.0332371439 -0.0342472679
#> AR -0.0161834913 -0.0197485094
#> AZ -0.0455633279 -0.0540328340
#> CA -0.0073736100 -0.0069451237
#> CO -0.0998324113 -0.2144934915
#> CT -0.0068844784 -0.0064218278
#> DC 0.1323688987 0.1625294726
#> DE 0.0194554114 0.0240963193
#> FL -0.0937513315 -0.1128399131
#> GA -0.0404177163 -0.0447775564
#> IA -0.0018353661 -0.0065783305
#> ID 0.0715311714 0.0827129047
#> IL 0.0364040836 0.0519384804
#> IN 0.3815562061 0.5127737560
#> KS 0.3195998033 0.3735174115
#> KY 0.0180534996 0.0284589475
#> LA -0.0034512710 0.0002398266
#> MA 0.0350797588 0.0495612406
#> MD -0.0061851180 0.0030358059
#> ME -0.1205435796 -0.1434406842
#> MI -0.0104773953 -0.0097225674
#> MN 0.0658291099 0.0815773829
#> MO 0.1658471055 0.2092785032
#> MS 0.0757674725 0.0957259331
#> MT -0.2226956530 -0.2848157760
#> NC -0.0801849629 -0.0930100202
#> ND 0.1471279546 0.1632516890
#> NE -0.0067148446 -0.0091668294
#> NH -0.0288545182 -0.0318590020
#> NJ 0.0419945037 0.0452393238
#> NM -0.3402646109 -0.4196645043
#> NV -0.0319233561 -0.0379518075
#> NY -0.0458677598 -0.0460468454
#> OH 0.0053817946 0.0082642996
#> OK -0.0197739286 -0.0218087721
#> OR -0.0312838479 -0.0325376041
#> PA 0.0548995292 0.0837696293
#> RI -0.0301300132 -0.0360929264
#> SC -0.0627597227 -0.0749119310
#> TN 0.0327156573 0.0397181302
#> TX 0.0813191504 0.0826967005
#> UT -0.0078590502 -0.0157365323
#> VA -0.0007437153 0.0095222182
#> VT -0.1811751876 -0.2204967507
#> WA -0.0090309685 -0.0112995414
#> WI -0.0244199376 -0.0283874222
#> WV -0.0755127962 -0.0908736075
#> medListPriceSqft:house_typeC medListPriceSqft:timeperiodbefore_2012
#> AL -0.0161539511 -0.033273312
#> AR -0.0143981558 -0.002542357
#> AZ -0.0354905346 -0.022865789
#> CA -0.0023188159 -0.016206762
#> CO -0.1891388131 -0.044702463
#> CT -0.0025396683 -0.007847727
#> DC 0.0915280219 0.147291653
#> DE 0.0138827021 0.019724991
#> FL -0.0701567701 -0.084079270
#> GA -0.0260708779 -0.036974280
#> IA -0.0102049733 0.015404515
#> ID 0.0420144801 0.079569678
#> IL 0.0595382970 -0.072987720
#> IN 0.4171418424 -0.035008222
#> KS 0.1945214096 0.349026709
#> KY 0.0298359996 -0.024003880
#> LA 0.0102208245 -0.036621369
#> MA 0.0494285509 -0.034373164
#> MD 0.0074462978 -0.007041631
#> ME -0.0886152719 -0.076925785
#> MI -0.0009559257 -0.024871313
#> MN 0.0334029227 0.132315832
#> MO 0.1447632248 0.074557543
#> MS 0.0624490008 0.054095381
#> MT -0.2229587595 0.002527347
#> NC -0.0581766037 -0.062570993
#> ND 0.0566945904 0.254531126
#> NE -0.0065563090 -0.003424448
#> NH -0.0121567614 -0.046952309
#> NJ 0.0457664635 -0.067748718
#> NM -0.2712390810 -0.211903077
#> NV -0.0242007544 -0.018678370
#> NY -0.0430582366 0.108457835
#> OH 0.0151824401 -0.038200489
#> OK -0.0100685546 -0.023278317
#> OR -0.0151429366 -0.036220790
#> PA 0.0781025694 -0.026947879
#> RI -0.0300959629 0.012527652
#> SC -0.0372963600 -0.092552679
#> TN 0.0308868734 -0.001932841
#> TX 0.0381596134 0.076102496
#> UT -0.0305654079 0.070222766
#> VA 0.0037802116 0.046899465
#> VT -0.1400341335 -0.118380902
#> WA -0.0022661974 -0.027577840
#> WI -0.0106677175 -0.046255988
#> WV -0.0542188035 -0.060304313
# make marginal effects accessible
## Average increase in medListPriceSqft-Slope for house_typeA and timeperiodbefore_2012
fixef(mod2)["medListPriceSqft:house_typeA"] + fixef(mod2)["medListPriceSqft:timeperiodbefore_2012"]
#> medListPriceSqft:house_typeA
#> 0.0434667
## Average increase in medListPriceSqft-Slope for house_typeA ()
prop_before_2012 <- table(df2$timeperiod)["before_2012"] / nrow(df2)
fixef(mod2)["medListPriceSqft:house_typeA"] +
fixef(mod2)["medListPriceSqft:timeperiodbefore_2012"] * prop_before_2012
#> medListPriceSqft:house_typeA
#> 0.03564273
## Average increase in medListPriceSqft-Slope for timeperiodbefore_2012
# ...
## Average increase in medListPriceSqft-Slope for house_typeA () for state == "WA"
# ...
As you see, this get's tedious quickly, how can I do this programmatically? The packages {margins} or {ggeffects} seem to cover marginal effects for the output only?

Why is flexsurvreg failing in this painfully simple case?

Behold the painfully simple case and the error(s). Comments inline.
library(flexsurv)
#> Loading required package: survival
library(tidyverse)
library(magrittr)
#>
#> Attaching package: 'magrittr'
#> The following object is masked from 'package:purrr':
#>
#> set_names
#> The following object is masked from 'package:tidyr':
#>
#> extract
set.seed(2019)
train_data <- tribble(
~wait_time, ~called_yet, ~time_queued,
131.282999992371, 0, 1570733365.28,
358.296000003815, 1, 1570733421.187,
1352.13999986649, 1, 1570733540.923,
1761.61400008202, 0, 1570733941.343,
1208.25300002098, 0, 1570734327.11,
522.296999931335, 1, 1570734376.953,
241.75, 0, 1570734659.44,
143.156999826431, 0, 1570734809.673,
1202.79999995232, 1, 1570734942.907,
614.640000104904, 1, 1570735526.567
)
# Base survival works fine!
survival_model <- survreg(Surv(wait_time, called_yet) ~ time_queued,
data = train_data,
dist = "weibull")
survival_model
#> Call:
#> survreg(formula = Surv(wait_time, called_yet) ~ time_queued,
#> data = train_data, dist = "weibull")
#>
#> Coefficients:
#> (Intercept) time_queued
#> 4.533765e+05 -2.886352e-04
#>
#> Scale= 0.518221
#>
#> Loglik(model)= -40.2 Loglik(intercept only)= -40.5
#> Chisq= 0.5 on 1 degrees of freedom, p= 0.48
#> n= 10
# flexsurvreg can't even get a valid initializer for time_queued, even though
# the doc says it takes the mean of the data
flexsurv_model <- flexsurvreg(Surv(wait_time, called_yet) ~ time_queued,
data = train_data,
dist = "weibull")
#> Error in flexsurvreg(Surv(wait_time, called_yet) ~ time_queued, data = train_data, : Initial value for parameter 2 out of range
# Maybe the low variance of the predictor here is the problem? So let's up the
# variance just to see
train_data %<>% mutate_at("time_queued", subtract, 1.57073e9)
train_data
#> # A tibble: 10 x 3
#> wait_time called_yet time_queued
#> <dbl> <dbl> <dbl>
#> 1 131. 0 3365.
#> 2 358. 1 3421.
#> 3 1352. 1 3541.
#> 4 1762. 0 3941.
#> 5 1208. 0 4327.
#> 6 522. 1 4377.
#> 7 242. 0 4659.
#> 8 143. 0 4810.
#> 9 1203. 1 4943.
#> 10 615. 1 5527.
# Now it initializes, so that's different... but now it won't converge!
flexsurv_model <- flexsurvreg(Surv(wait_time, called_yet) ~ time_queued,
data = train_data,
dist = "weibull")
#> Warning in flexsurvreg(Surv(wait_time, called_yet) ~ time_queued, data
#> = train_data, : Optimisation has probably not converged to the maximum
#> likelihood - Hessian is not positive definite.
Created on 2019-10-19 by the reprex package (v0.3.0)
I mainly wanted to use flexsurv for its better plotting options and more standard shape & scale definitions - and the ancillary parameters are very attractive too - but now I'm mainly just wondering if I'm doing something really wrong, and flexsurv is trying to tell me not to trust my base survival model either.
Marco Sandri pointed out that recentering fixes it; however, recentering without rescaling only guarantees initialization, and still results in no convergence if the variance is very large. I'm considering this a bug since survival has no problem with the exact same model with the exact same values. Created an issue here.

Resources