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!

3
  • 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 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. Commented Jul 11, 2016 at 16:01
  • Thanks for the tip, and the clarification on the [[ use Commented Jul 12, 2016 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. Commented Jul 12, 2016 at 13:24

2 Answers 2

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(...))

Sign up to request clarification or add additional context in comments.

5 Comments

Ops, I didn't see you solution on time. Sorry for posting such a similar answer.
yours is simpler. The only advantage of my answer is the explanation/suggestions at the top.
(I've now streamlined mine ...)
I can see you're having fun with it kkkk. =)
Thanks for the explanation and the solution! Those are exactly what I was expecting, now I see what went wrong.
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)
}

Comments

Your Answer

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