-1

I have a dataframe with various variables.

'data.frame':   324 obs. of  13 variables:
 $ caldt     : Date, format: "1990-01-31" "1990-02-28" "1990-03-30" 
 $ X30bd     : num  -0.0429 -0.00595 -0.00265 -0.03033 0.04894 ...
 $ X20bd     : num  -0.0396 -0.00269 -0.00227 -0.02729 0.04885 ...
 $ X10bd     : num  -0.02441 -0.00207 -0.0017 -0.0174 0.03283 ...

...

I create a vector containing the variables of interest on which I want to perform analysis.

endowmentAssetClasses <- c("X30bd", "X20bd")

I want to create a different R object for each variable on which I will perform analysis.

for (i in endowmentAssetClasses) {
     paste0(i,".gpd.fit") <- gpd.tail(paste0("endowMVEVdata$",i),upper=quantile(paste0("endowMVEVdata$",i),0.9), 
                     lower=quantile(paste0("endowMVEVdata$",i),0.1))
}

I get an error though,

non-numeric argument to binary operator

meaning that I am referencing the vector "endowMVEVdata$X30bd" and so forth as characters, but I am at a loss to create the gpd object

x30bd.gpd.fit

and

x20gd.gpd.fit 

to contain the output from the function "gpd.tail" in a "loop." Everything works fine if I type the names directly, with a line entry for each variable I want the analysis, but how can I reference the vectors in a look so that the function recognizes numeric data instead of a character?

fibrou
  • 313
  • 1
  • 5
  • 15

1 Answers1

1

Like @akrun said, you could indeed make it work with assign and get.

It would look like:

for (i in endowmentAssetClasses) {
  assign(
    paste0(i, ".gpd.fit"),
    gpd.tail(
      endowMVEVdata[[i]], 
      upper = quantile(endowMVEVdata[[i]], 0.9), 
      lower = quantile(endowMVEVdata[[i]], 0.1)
    )
  )
}

Actually, get is not needed here. get(paste0("endowMVEVdata$", i)) wouldn't work. eval(parse(text = paste0("endowMVEVdata$", i))) would, but really, don't.

But:

fortunes::fortune(236)
# The only people who should use the assign function are those who fully
# understand why you should never use the assign function.
# -- Greg Snow
# R-help (July 2009)

The R way is not to work with multiple variables in your workspace and loops, but rather to store similar things in lists and pass them to functions. A direct translation would be:

gpd.fit.list <- lapply(
  setNames(nm = endowmentAssetClasses),
  function(x) gpd.tail(
    endowMVEVdata[[x]], 
    upper = quantile(endowMVEVdata[[x]], 0.9), 
    lower = quantile(endowMVEVdata[[x]], 0.1)
  ) 
)

Or more simply:

gpd.fit.list <- lapply(
  endowMVEVdata[, endowmentAssetClasses, drop = FALSE],
  function(y) gpd.tail(y, upper = quantile(y, 0.9), lower = quantile(y, 0.1))
)

Note that this code is not tested, so it may not work without some adaptation. You should provide a minimal reproducible example.

Aurèle
  • 12,545
  • 1
  • 31
  • 49
  • Thanks for both replies. The simple approach from Aurele worked wonderfully, on a test set of variables, then the function crashed on a couple of others. So, I'm not going to be able to automate this like I thought. Thanks again for both replies. – fibrou May 25 '17 at 13:02