afleishman
afleishman

Reputation: 433

Using r for loop to create new columns in data frame

I'm trying to create a for loop in r to 1. create new columns in a dataframe and 2. calculate some simple expression over multiple variables.

My dataframe has 10 columns and 22 rows

df <- setNames(data.frame(replicate(22,sample(0:10,10,rep=TRUE))), 
     sprintf("rmeas%s",seq(from = 0, to = 84, by = 4)))

I'd like to create a simple for loop to create 21 new columns named 'rmaster' followed by a number (4-84 by 4). The first new column (df$rmaster4) will be populated by the following calculation:

df$rmaster4 <- (df$rmeas4^3 + df$rmeas0*df$rmeas4+ df$rmeas0^2) / 2.12352

So far, I have the following code:

for(i in seq(from = 0, to = 84, by = 4)) {

assign("df", `$<-`(df, paste0("rmaster", i+4), 
              (get(paste0("x$rmeas", i+4))^3 + 
                 get(paste0("x$rmeas", i))*get(paste0("x$rmeas", i+4)) + 
                 get(paste0("x$rmeas", i+4))^2) / 2.12352))
}

There seems to be a lot going wrong here. For starters, I want to create rmaster4-rmaster84 and this code would create rmaster4-rmaster88. Next, I know I can't use the get() function in the way that I have. Unfortunately, I am unable to remedy the problems. Any insight would be greatly appreciated.

Upvotes: 0

Views: 10084

Answers (1)

Michael Lachmann
Michael Lachmann

Reputation: 146

First, answering your question, and following eddi's comment above, this would be the right code:

for(i in seq(from = 0, to = 80, by = 4)) {
       print(paste0("rmeas", i+4))
         df[ , paste0("rmaster", i)] = ( df[ ,paste0("rmeas", i+4)] ^3 +
               df[ , paste0("rmeas", i)] * df[ ,paste0("rmeas", i+4)] + 
               df[ , paste0("rmeas", i+4)] ^2 ) / 2.12352
}

Notice that I only went up to i=80, because there is no rmeas88 column.

A more R style way to do the same would be:

 i.v=  seq(from = 0, to = 80, by = 4)
 A = sapply( i.v, function(i) {
             ( df[ ,paste0("rmeas", i+4)] ^3 +
               df[ , paste0("rmeas", i)] * df[ ,paste0("rmeas", i+4)] + 
               df[ , paste0("rmeas", i+4)] ^2 ) / 2.12352
})
colnames(A) = paste0( "rmaster", i.v)
df = cbind( df, A )

Upvotes: 3

Related Questions