1

In R, I have several data frames with the same structure (3 columns and several rows). All data frames follow the same naming conventions and have the same data structure, so they can be listed with an ls(pattern="NamePrefix") call.

I wanted to use a for loop to rename the second and third variable of all those data frames. Here is the code that I tried:

for (i in ls(pattern="NamePrefix"))
{
    names(i)[[2]] <- "NewName"
    names(i)[[3]] <- "OtherNewName"
}

I have also tried setting the names of the data frames as list first (by File_List <- ls(pattern="NamePrefix")) and then using that list in the loop (for (i in File_List)), but that doesn't work either.

Whatever I do, I get this error:

Error in names(i)[[2]] <- "NewName" :
'names' attribute [2] must be the same length as the vector [1]

However, if I simply do names(SomeDataset)[[2]] <- "NewName" that works perfectly. Yet somehow the for loop appears incapable of running it.

Any ideas as to why does it happen and how to fix it? Note that I am well aware of several other alternatives to do the same loop renaming over several data frames without using names(), but this was a far simpler, more intuitive alternative (I thought) and I can't see why the loop seems incapable of implementing it. So, now I want to understand why the solution that I thought was the simplest appears to be wrong (and if possible, how to fix it so that it works).

Thanks in advance!

  • First, use `names(df)[2] <- "someName"` Do not use `[[` as it is for accessing list items. It is often advantageous to store similar data.frames in a list. See the [this post](http://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames) on how to put data.frames into lists. In particular, gregor's answer there gives a number of useful methods for working with data.frames in lists. – lmo Jul 11 '16 at 16:01
  • Thanks for the tip, and the clarification on the `[[` use –  Jul 12 '16 at 13:15
  • I should clarify that `[[` will technically work most of the time on vectors, but it can result in unintended consequences, such as stripping attributes from the vector. So using `[` is usually what you want to do. `[[` can be quite helpful when working with lists. – lmo Jul 12 '16 at 13:24

2 Answers2

3

Because i will be a character object naming the object, not the object itself. I can't actually think of a nice way to do this; the general advice for "how do I do xxxx to a bunch of objects that are all named similarly?" is "store those objects in a list" ...

dd <- data.frame(a=1,b=2,c=3)
for (i in ls(pattern="^dd")) {
    g <- get(i)
    names(g)[2:3] <- c("NewName","OtherNewName")
    assign(i,g)
}

There's probably also a solution based on (ugh) eval(parse(...))

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
3
#Creating data frames
df1 <- data.frame("V1"=rnorm(10,1,10),"V2"=rnorm(10,1,10),"V3"=rnorm(10,1,10))
df2 <- data.frame("V1"=rnorm(10,1,10),"V2"=rnorm(10,1,10),"V3"=rnorm(10,1,10))
df3 <- data.frame("V1"=rnorm(10,1,10),"V2"=rnorm(10,1,10),"V3"=rnorm(10,1,10))
df4 <- data.frame("V1"=rnorm(10,1,10),"V2"=rnorm(10,1,10),"V3"=rnorm(10,1,10))
df5 <- data.frame("V1"=rnorm(10,1,10),"V2"=rnorm(10,1,10),"V3"=rnorm(10,1,10))

# Creating a list of data frames
df_list <- ls(pattern="df")

# Renaming the variables in the data frame
for(i in df_list){
  aux <- get(i)
  names(aux)[2:3] <- c("Vari2","Vari3")
  assign(i,aux)
}
Diego Rodrigues
  • 824
  • 4
  • 10