как указать в формуле R с некоторыми независимыми переменными, имеющими пробелы - PullRequest
0 голосов
/ 30 марта 2020

Я использую ucm в R. Есть аргумент формулы для этого. У меня есть переменная ответа y и два предиктора с именем "abc def" and jkl. Я хочу, чтобы формула выглядела как y ~ abc def + jkl. Но пробел между ab c и def является проблемой. Как указать формулу, чтобы R понимал, что ab c def - это только одно имя? Прямо сейчас я получаю ошибку "Error in terms.formula(formula) : '.' in formula and no 'data' argument", когда задаю формулу, как показано ниже.

ucm_Forecast=function(x,h,xreg){
  if (ncol(xreg)>=1){   
    xregFit=data.frame(xreg[1:length(x),])
    x<-x/10000
    d<-cbind(data.frame(x=x),xregFit)
    fit_ucm=ucm(**x~.**,data=d, level = TRUE, slope=TRUE, cycle = TRUE, cycle.period = 365.25/52)        

    print("right before predict")  
    indep <- paste(names(d)[2:ncol(d)], collapse= "+")
    newdata1 <- SSModel(as.formula(paste0("rep(NA,h) ~ ", indep, 
                                          "+ SSMtrend(2, Q =  list(fit_ucm$est.var.level,fit_ucm$est.var.slope))",
                                          "+ SSMcycle(365.25/52, Q = fit_ucm$est.var.cycle)")), 
                        H = fit_ucm$irr.var, data=as.data.frame(xreg[(length(x)+1):(length(x)+h),]))
    fcst<-predict(fit_ucm$model, newdata=newdata1)

    #fcst<-predict(fitucm$model, xreg=xreg[(length(x)+1):(length(x)+h),])
    print("right after predict")
    fcst<-fcst*10000
    print(fcst)
  } else {
    x=ts(filter(Model_Dataset,Category==Cat,Date<FcstDate)$`Gross Sales`)
    x<-x*10000
    x<-x/10000
    x<-ts(x)
    x
    fitucm<- ucm(formula = x~0, data = x, level = TRUE, slope=TRUE)
    fcst<-predict(fitucm$model, n.ahead = h)
    fcst<-fcst*10000
    fcst
  }
  return(fcst)
}

Отредактированный код в соответствии с ответом r2evans приведен ниже. Теперь я получаю ошибку

Error in eval(predvars, data, env) : 
  object 'abc.def' not found
Called from: eval(predvars, data, env)

Отредактированный код

 ucm_Forecast=function(x,h,xreg){

      print("h=")
      print(h)
      if (ncol(xreg)>=1){


         xregFit=data.frame(xreg[1:length(x),])
        # xregFcst=data.frame(xreg[(length(x)+1):nrow(xreg),])
        # 
        # colnames(xregFit)=colnames(xreg)
        # colnames(xregFcst)=colnames(xreg)
        x<-x/10000
        d<-cbind(data.frame(x=x),xregFit)
        #fit_ucm=ucm(x~.,data=d, level = TRUE, slope=TRUE, cycle = TRUE, cycle.period = 365.25/52)



        independent <- paste0("`", names(d)[-1], "`", collapse = " + ")

        #d<-cbind(as.data.frame(x),xreg[1:length(x),])

      fit_ucm<- ucm(as.formula(paste("`",names(d[1]),"` ~", independent)), data = d, level = TRUE, slope=TRUE, cycle = TRUE, cycle.period = 365.25/52)
        #fit_ucm<- ucm(formula=x~Shipping_Days+Orders_Min_2_Weeks+Orders_Pre_1_Weeks, data = d, level = TRUE, slope=TRUE, cycle = TRUE, cycle.period = 365.25/52)
      #  fit_ucm<- ucm(as.formula(paste0(names(d[1]),"~.")), data = d, level = TRUE, slope=TRUE, cycle = TRUE, cycle.period = 365.25/52)
         print("right before predict")


        indep <- paste(names(d)[2:ncol(d)], collapse= "+")
        newdata1 <- SSModel(as.formula(paste0("rep(NA,h) ~ ", indep, 
                                              "+ SSMtrend(2, Q =  list(fit_ucm$est.var.level,fit_ucm$est.var.slope))",
                                              "+ SSMcycle(365.25/52, Q = fit_ucm$est.var.cycle)")), H = fit_ucm$irr.var, data=as.data.frame(xreg[(length(x)+1):(length(x)+h),]))
        fcst<-predict(fit_ucm$model, newdata=newdata1)

        #fcst<-predict(fitucm$model, xreg=xreg[(length(x)+1):(length(x)+h),])
        print("right after predict")
        fcst<-fcst*10000
        print(fcst)

      } else {

        x=ts(filter(Model_Dataset,Category==Cat,Date<FcstDate)$`Gross Sales`)
        x<-x*10000
        x<-x/10000
        x<-ts(x)

        x
        fitucm<- ucm(formula = x~0, data = x, level = TRUE, slope=TRUE)
        fcst<-predict(fitucm$model, n.ahead = h)
        fcst<-fcst*10000
        fcst
      }

      return(fcst)
    }

Я поставил check.names = FALSE, но я все еще получаю другую ошибку.

Error in `[.data.frame`(data, , as.character(dep.var)) : 
  undefined columns selected
Called from: `[.data.frame`(data, , as.character(dep.var))

Вот код.

ucm_Forecast=function(x,h,xreg){

  print("h=")
  print(h)
  if (ncol(xreg)>=1){


     xregFit=data.frame(xreg[1:length(x),],check.names=FALSE)
    print( colnames(xregFit))

    x<-x/10000
    d<-cbind(data.frame(x=x),xregFit)


    independent <- paste0("`", names(d)[-1], "`", collapse = " + ")
    print("dfgh")

**The statement below errors out**  
  fit_ucm<- ucm(as.formula(paste("`",names(d[1]),"` ~", independent)), data = d, level = TRUE, slope=TRUE, cycle = TRUE, cycle.period = 365.25/52)

     print("right before predict")


    indep <- paste(names(d)[2:ncol(d)], collapse= "+")
    newdata1 <- SSModel(as.formula(paste0("rep(NA,h) ~ ", indep, 
                                          "+ SSMtrend(2, Q =  list(fit_ucm$est.var.level,fit_ucm$est.var.slope))",
                                          "+ SSMcycle(365.25/52, Q = fit_ucm$est.var.cycle)")), H = fit_ucm$irr.var, data=as.data.frame(xreg[(length(x)+1):(length(x)+h),]))
    fcst<-predict(fit_ucm$model, newdata=newdata1)

    #fcst<-predict(fitucm$model, xreg=xreg[(length(x)+1):(length(x)+h),])
    print("right after predict")
    fcst<-fcst*10000
    print(fcst)

  } else {

    x=ts(filter(Model_Dataset,Category==Cat,Date<FcstDate)$`Gross Sales`)
    x<-x*10000
    x<-x/10000
    x<-ts(x)


    fitucm<- ucm(formula = x~0, data = x, level = TRUE, slope=TRUE)
    fcst<-predict(fitucm$model, n.ahead = h)
    fcst<-fcst*10000
    fcst
  }

  return(fcst)
}

1 Ответ

1 голос
/ 30 марта 2020

Программно:

names(mtcars)[2] <- "cyl cyl"
sprintf(ifelse(grepl(" ", names(mtcars)), "`%s`", "%s"), names(mtcars))
#  [1] "mpg"       "`cyl cyl`" "disp"      "hp"        "drat"      "wt"        "qsec"     
#  [8] "vs"        "am"        "gear"      "carb"     

Я думаю, что вы можете использовать это непосредственно в своем коде, возможно, с (непроверенным):

    indep <- names(d)[-1]
    indep <- sprintf(ifelse(grepl(" ", indep), "`%s`", "%s"), indep)
    indep <- paste(indep, collapse = "+")

(Я уверен, что для удобства чтения Вы можете компактифицировать этот код.)

Или вы можете просто всегда помешать всему, поскольку он все еще работает, даже если в этом нет необходимости.

    indep <- paste0("`", names(d)[-1], "`", collapse = "+")

Демонстрация, используя mtcars и lm:

names(mtcars)[2] <- "cyl cyl"
indep <- sprintf(ifelse(grepl(" ", names(mtcars)[-1]), "`%s`", "%s"), names(mtcars)[-1])
indep <- paste(indep, collapse = " + ")
indep
# [1] "`cyl cyl` + disp + hp + drat + wt + qsec + vs + am + gear + carb"
lm(as.formula(paste("mpg ~", indep)), data = mtcars)
# Call:
# lm(formula = as.formula(paste("mpg ~", indep)), data = mtcars)
# Coefficients:
# (Intercept)    `cyl cyl`         disp           hp         drat           wt         qsec  
#    12.30337     -0.11144      0.01334     -0.02148      0.78711     -3.71530      0.82104  
#          vs           am         gear         carb  
#     0.31776      2.52023      0.65541     -0.19942  

и

indep <- paste0("`", names(mtcars)[-1], "`", collapse = " + ")
indep
# [1] "`cyl cyl` + `disp` + `hp` + `drat` + `wt` + `qsec` + `vs` + `am` + `gear` + `carb`"
lm(as.formula(paste("mpg ~", indep)), data = mtcars)
# Call:
# lm(formula = as.formula(paste("mpg ~", indep)), data = mtcars)
# Coefficients:
# (Intercept)    `cyl cyl`         disp           hp         drat           wt         qsec  
#    12.30337     -0.11144      0.01334     -0.02148      0.78711     -3.71530      0.82104  
#          vs           am         gear         carb  
#     0.31776      2.52023      0.65541     -0.19942  

Редактировать : вероятна следующая ошибка, которую вы видите (object 'abc.def' not found) вам переосмысление вещей. Используя измененный mtcars ранее,

data.frame(mtcars[1:3,])
#                mpg cyl.cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4     21.0       6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag 21.0       6  160 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710    22.8       4  108  93 3.85 2.320 18.61  1  1    4    1

data.frame(mtcars[1:3,], check.names = FALSE)
#                mpg cyl cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4     21.0       6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag 21.0       6  160 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710    22.8       4  108  93 3.85 2.320 18.61  1  1    4    1

Обратите внимание, что в первом примере имя "cyl cyl" было заменено на "cyl.cyl". Это поведение можно подавить с помощью check.names = FALSE, как показано во втором примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...