How extract parameter model intable?

Viewed 53

I am trying to extract different parameters from a table and place them in a column each. I have tried but it did not work.

This is the example

  Models = c("ARIMA(1,0,10)(80,0,90)[12] with non-zero mean",
           "ARIMA(2,0,11) with non-zero mean",
           "ARIMA(3,0,12)(81,0,91)[12] with non-zero mean",
           "ARIMA(4,0,13)(82,0,92)[12] with non-zero mean",
           "ARIMA(5,0,14) with zero mean",
           "ARIMA(6,0,15) with non-zero mean")

Models = as.data.frame(Models)

I need to separate each parameter in a different column the idea is to separate it as follows

   Name p d  q   P   D   Q  PERIOD  MEAN
1 ARIMA 1 0 10  80   0  90   12     with non-zero mean
2 ARIMA 2 0 11 N/a N/a N/a   N/a    with non-zero mean
3 ARIMA 3 0 12  81   0  91   12     with non-zero mean
4 ARIMA 4 0 13  82   0  92   12     with non-zero mean
5 ARIMA 5 0 14 N/a N/a N/a   N/a    with zero mean
6 ARIMA 6 0 15 N/a N/a N/a   N/a    with non-zero mean

Is there a way to separate it automatically? I am new working with R I have researched but I can not find the solution

note: the models that are in examples are not real, it is only to identify the parameters

2 Answers

I'm not sure how this performs on your original data set but seems to work fine here:

library(dplyr)
library(stringr)
library(tidyr)

Models %>%
  as_tibble() %>%
  mutate(Mean = str_extract(value, "(?<=\\s)[^d]+"),
         value = gsub("\\s[^d]+", "", value), 
         value = gsub("[)(,]", " ", value, perl = TRUE),
         value = gsub("[\\[\\]]", "", value, perl = TRUE)) %>%
  separate(value, into = c("Name", "p", "d", "q", "P", "D", "Q", "Period"), sep = "\\s+") %>%
  mutate(across(p:Q, ~ replace(., . == (""), NA)))

# A tibble: 6 x 9
  Name  p     d     q     P     D     Q     Period Mean              
  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>  <chr>             
1 ARIMA 1     0     10    80    0     90    12     with non-zero mean
2 ARIMA 2     0     11    NA    NA    NA    NA     with non-zero mean
3 ARIMA 3     0     12    81    0     91    12     with non-zero mean
4 ARIMA 4     0     13    82    0     92    12     with non-zero mean
5 ARIMA 5     0     14    NA    NA    NA    NA     with zero mean    
6 ARIMA 6     0     15    NA    NA    NA    NA     with non-zero mean

I think you're going to have to build something yourself. As a start, try (*starting from the character vector version of Models, i.e. before converting to a data frame - or, if you already have a data frame, use Models[[1]] instead of Models in the first step).

m <- gsub("with (.*) mean","with_\\1_mean",Models)
mm <- strsplit(m, "[(), ]")

This first converts the spaces in "with zero/non-zero mean" to underscores, then splits the strings anywhere it finds characters in the set (), .

You can use lengths(mm) to figure out whether P/D/Q/period are present or not (the value will be 10 if they are, 6 otherwise). Something clunky like

insert_na <- function(x) c(x[1:5], rep(NA,4), x[6])
mm[lengths(mm)==6] <- lapply(mm[lengths(mm==6)], insert_na)

might work, although I haven't tested it.

Once you've gone through inserting NA values in the right places you can do something like

do.call(rbind,mm[sapply(mm, length) == 10])

to put them together (here I subsetted to include only the length-10 values). Then you might want to make the result into a data frame and convert the appropriate columns to numeric ... there will be other cleanup to do (remove spurious characters, add column names, etc.)

Related