3

I would like to write an expression in R where I can modify some part of it depending on some other variable. For example, let's say that I want to create a lot of new columns in my data frame using the following basic expression:

MyDataFrame$ColumnNumber1 <- 33

If I wanted to create a lot of these, I could just type them out explicitly

MyDataFrame$ColumnNumber2 <- 52
MyDataFrame$ColumnNumber3 <- 12
...

and so on. However, this would be impractical if I have to many of them. Therefore, I'd like to have some way of replacing a part of the expression with something that's generated through a variable. Let's for example say that there was an operator Input() that would do this. Then I could write a function looking like this:

for(i in 1:1000)
{
    MyDataFrame$ColumnNumberInput(i) <- 32*i
}

where the Input(i) part would be replaced with whatever number the counter were at at the moment, which in turn would generate an expression.

I now that I can do this by using:

eval(parse(text=paste("MyDataFrame$","Column","Number","1","<- 32*i",sep="")))

but this gets impossible to use if the expression is too complicated, long, or have other things like this nested inside of it.

5
  • 2
    why do you want to proceed this way?? you can simply do do.call(cbind, list(df, lapply(1:10, function(u) setNames(data.frame(u*32),u)))) Commented Apr 25, 2015 at 12:45
  • 2
    MyDataFrame[, paste0("ColumnNumber", i) <- 52? It's not obvious what exactly you are trying to achieve. There might be a better approach. Commented Apr 25, 2015 at 12:56
  • There are occasions where using the [[]] operator, which is what I think @Speldose wants here, is helpful. Literate programming, where ease of maintenance and readability are given priority over efficiency, come to mind. That said, this approach does lend itself to "speaking R with a C accent," and thus should be used with caution. If you don't need to prioritize readability, consider the approach suggested by @ColonelBeauvel. Commented Apr 25, 2015 at 14:48
  • @ColonelBeauvel That would work for this specific case, but I find it less readable than @JustinFletcher's solution. Also, I was on the hunt for something more general (for example, what if I want to use some kind of terminal input to name my columns?) and my example was just a narrow example. @Roland's solution might have worked for what I was trying to do in this case, but what I'm really after is a general way of generating text that becomes a part of an expression which then is evaluated. Something like "\Input(x)" is ALWAYS replaced with x no matter where it's placed. Commented Apr 25, 2015 at 15:27
  • Work with the language, not against it ... Commented Apr 25, 2015 at 17:15

1 Answer 1

2

Use [[]]:

for(i in 1:1000)
{
    MyDataFrame[[i]] <- 32*i
} 

[[]] is the programmatic equivalent of $.

You may then reference the data structure as:

MyDataFrame[[14]] <- MyDataObjFourteen
MyDataFrame$14
MyDataFrame[[14]]

You could also use strings, like so:

MyDataFrame[["SomeString"]] <- 32
MyDataFrame$SomeString
# 32

EDIT 1:

To do something similar, in a more general way try:

assign("someArbitraryString", 3)
someArbitraryString
# 3
as.name(someArbitraryString)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! This worked for my specific problem. I'm still on the look for a more general way to do this though (see my comment on my original question).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.