Joshua Daly
Joshua Daly

Reputation: 626

Applying functions to variable references rather than copies in R

Context

I have multiple data.table, each assigned to their own variable, dt1, dt2 etc. I wanted to apply a function to dt1, dt2, ..., and preserve the original variable names. I wanted to avoid hard-coded syntax like dt1 <- foo(dt1), dt2 <- foo(dt2). My solution is below.

dataSets <- list(dt1 = dt1, dt2 = dt2, dt3 = dt3, dt4 = dt4, dt5 = dt5)
for (i in 1:length(dataSets)) {
  dataSet <- dataSets[[i]]
  name <- names(dataSets)[i]
  assign(name, foo(dataSet))
}

I don't think my solution is very elegant. I dislike how I'm using name and assign.

Question

How, if possible, can I rework what I've done, to avoid needing name and assign?

My Thoughts

I imagine the solution might involve working with references to dt1, dt2, ...., rather than copies. I thought of creating a referenceList. It wouldn't copydt1, dt2, .... Instead, it would point to those variables. I imagined creating a referenceList, like rl <- referenceList(dt1). Then, applying foo to rl, foo(rl[1]) would change dt1.

Upvotes: 1

Views: 44

Answers (1)

user2554330
user2554330

Reputation: 44897

R doesn't have a way to create references to variables in general. (Some kinds of objects, e.g. environments, are always dealt with via references, but most aren't.)

The usual way to do something like what you're doing is to put the objects in a list, and just work on the list, without bothering to extract them again. For example,

dataSets <- list(dt1 = dt1, dt2 = dt2, dt3 = dt3, dt4 = dt4, dt5 = dt5)
for (i in seq_along(dataSets) {
  dataSets[[i]] <- foo(dataSets[[i]])
}

If you really want the results back in the original objects, I wouldn't bother putting all of those objects into a list, I'd work on a vector of names. For example:

names <- paste0("dt", 1:5)
for (i in seq_along(names)) {
  assign(names[i], foo(get(names[i])))
}

But this is much less elegant than just working with the data in a list.

Upvotes: 2

Related Questions