Doug Fir
Doug Fir

Reputation: 21204

create names of loop when iterating data frame

mylist <- list(demographic_vars, usage_engagement_vars, billing_contracttype_vars, contract_type_vars)

Each variable in mylist is a dataframe.

I'm writing a function to pass to lapply(). I would like to loop over mylist and name a variable like so:

varData <- function(x) {
    paste('cv_prediction',x,sep='') <- data.frame()
}

Goal of the above would be this: (e.g. for the first iteration)

cv_predictiondemographic_vars <- data.frame()

I'm getting an error in my function that I suspect is related to the above.

Error in paste("cv_prediction", x, sep = "") <- data.frame() :
target of assignment expands to non-language object

If I want to create variables within my function that are the concatenation of the current value of x in a loop to some other string, how would I do that?

Upvotes: 1

Views: 895

Answers (2)

Konrad Rudolph
Konrad Rudolph

Reputation: 545508

It’s tricky. In general, you’d write the function like this:

varData = function(x) {
    name = paste0('cv_prediction', deparse(substitute(x), backtick = TRUE))
    assign(name, x, parent.frame())
}

This works when called like this, say:

varData(some_data_frame)

However, it won’t work with a loop variable since then it will use the name of that variable. As far as I know there’s no way of actually achieving what you want. Instead, you need to replace list in your above code by something else:

named_list = function (...) {
    names = sapply(match.call()[-1], deparse, backtick = TRUE)
    setNames(list(...), names)
}

And then use it:

mylist = named_list(demographic_vars, usage_engagement_vars, billing_contracttype_vars, contract_type_vars)

This will result in a mylist whose values are named by the objects. For example:

a = 1
b = 2
named_list(a, b)
# $a
# [1] 1
#
# $b
# [1] 2

Now you can start using the names of the list in your code.

Upvotes: 2

Vongo
Vongo

Reputation: 1434

You could consider using eval (see doc).

> varData <- function(x) {
+    eval(parse(text=paste('cv_prediction', x,' <<- data.frame()',sep='')))
+ }
> varData(3)
> ls()
[1] "cv_prediction3" "varData"
> class(cv_prediction3)
[1] "data.frame"

Note that instead of using <<- operator you can direcly address the environment where you want your new object to be created :

eval(parse(text=paste('cv_prediction', x,' <- data.frame()',sep='')),env=.GlobalEnv)

Upvotes: 1

Related Questions