1

[Working with R 3.2.2]

I have three data frames with the same variables. I need to modify the value of some variables and change the name of the variables (rename the columns). Instead of doing this data frame by data frame, I would like to use a loop.

This is the code I want to run:

#Change the values of the variables
vlist <- c("var1", "var2", "var3")
dataframe0[,vlist] <- dataframe0[,vlist]/10
dataframe1[,vlist] <- dataframe1[,vlist]/10
dataframe2[,vlist] <- dataframe2[,vlist]/10

#Change the name of the variables
colnames(dataframe0)[colnames(dataframe0)=="var1"] <- "temp_min"
colnames(dataframe0)[colnames(dataframe0)=="var2"] <- "temp_max"
colnames(dataframe0)[colnames(dataframe0)=="var3"] <- "prep"

colnames(dataframe1)[colnames(dataframe1)=="var1"] <- "temp_min"
colnames(dataframe1)[colnames(dataframe1)=="var2"] <- "temp_max"
colnames(dataframe1)[colnames(dataframe1)=="var3"] <- "prep"

colnames(dataframe2)[colnames(dataframe2)=="var1"] <- "temp_min"
colnames(dataframe2)[colnames(dataframe2)=="var2"] <- "temp_max"
colnames(dataframe2)[colnames(dataframe2)=="var3"] <- "prep"

I know the logic to do it with programs like Stata, with a forvalues loop:

#Change the values of the variables
forvalues i=0/2 {
dataframe`i'[,vlist] <- dataframe`i'[,vlist]/10

#Change the name of the variables
colnames(dataframe`i')[colnames(dataframe`i')=="var1"] <- "temp_min"
colnames(dataframe`i')[colnames(dataframe`i')=="var2"] <- "temp_max"
colnames(dataframe`i')[colnames(dataframe`i')=="var3"] <- "prep"
}

But, I am not able to reproduce it in R. How should I proceed? Thanks in advance!

Marina
  • 43
  • 4
  • 1
    `for(i in 0:2)` to do a `for` loop, but you probably want to work with a list of data.frames rather than separate data.frames. It will make the desired actions much easier. See gregor's answer to [this post](http://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames) for working with lists of data.frames. My answer there gives a simple method for putting similarly named data.frames into a list. – lmo Feb 08 '17 at 14:26
  • @Imo I tried with a for(i in 0:2). But, I don't know how to later call ´i´ in the code...At the moment, I want the data frames separated because they don't have the same number of columns, so afterwards I am joining them using ´write.csv(bind_rows(list(dataframe0, dataframe1, dataframe2)), "meansdf.csv")´ – Marina Feb 08 '17 at 14:44
  • I still recommend putting them in a list. read through the post I linked to, gregor's answer there will give you a number of examples that should help you to accomplish your intermediate steps. When you are ready, there is nothing to stop you from using `bind_rows`. I would even suspect that it might accept a list of data.frames as its argument, though I'm not familiar with the funciton. – lmo Feb 08 '17 at 14:48
  • @lmo seems so from previous comment: bind_rows( **list** (dataframe0, dataframe1, dataframe2)) – Tensibai Feb 08 '17 at 14:50
  • 1
    @Tensibai reading, Ugh. – lmo Feb 08 '17 at 14:56
  • @lmo unsure if you mean I've been rude or not, if so I'm sorry, I was just confirming your idea from OP's comment (which mean using a list is the best idea). Re reading your first comment, the link you provided seems a good dupe target in fact. – Tensibai Feb 08 '17 at 15:20
  • I am afraid I was not able to make your ideas work...Thank you in any case to both of you! – Marina Feb 10 '17 at 08:04

1 Answers1

1

I would go working with a list of dataframe, you can still 'split' it after if really needed:

df1 <- data.frame("id"=1:10,"var1"=11:20,"var2"=11:20,"var3"=11:20,"test"=1:10)
df2 <- df1
df3 <- df1

dflist <- list(df1,df2,df3)

for (i in seq_along(dflist)) {
  df[[i]]['test'] <- df[[i]]['test']/10
  colnames( dflist[[i]] )[ colnames(dflist[[i]]) %in% c('var1','var2','var3') ] <- c('temp_min','temp_max','prep')
  # eventually reassign df1-3 to their list value:
  # assign(paste0("df",i),dflist[[i]])
}

The interest of using a list is that you can access them a little more easily in a programmatic way.

I did change your code from 3 calls to only one, as colnames give a vector you can subset it and replace in one pass, this is assuming your var1 to var3 are always in the same order.

Addendum: if you want a single dataset at end you can use do.call(rbind,dflist) or with data.table package rbindlist(dflist).

More details on working with list of data.frames in Gregor's answer here

Community
  • 1
  • 1
Tensibai
  • 15,080
  • 1
  • 35
  • 53