1

I am trying to change the variable names in all data frames in a for loop. Any example of the data is:

df1 <- data.frame(
  Number = c(45,62,27,34,37,55,40),
  Day = c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
df2 <- data.frame(
  Number = c(15,20,32,21,17,18,13),
  Day = c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
df3 <- data.frame(
  Number = c(12,32,22,14,16,21,30),
  Day = c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun")

L <- list(df1,df2,df3)

My current attempt is:

for(i in L){
colnames(L) <- c("NewName1", "NewName2")
}

Which is not working, I do not understand why it is not working. Please let me know if someone can guide me in the right direction.

4
  • 2
    If your for loop is for (i in L), then you need to use i inside the loop. In this case, you're better off using integer indexes to loop over: for(i in seq_along(L)){colnames(L[[i]]) = c("NewName1", "NewName2")}. Commented Apr 5, 2018 at 15:41
  • Generally avoid for loops, they're slower in R than other solutions, like the apply function in Jilber's answer below. For some info on why, see here. Commented Apr 5, 2018 at 15:47
  • @Anonymouscoward: apply is not faster than for loop. The "apply function has a for loop in its definition. The lapply function buries the loop, but execution times tend to be roughly equal to an explicit for loop" (burns-stat.com/pages/Tutor/R_inferno.pdf). What makes a for loop slow and memory hog is growing object within the loop. Commented Apr 5, 2018 at 16:51
  • @Tung, we may be getting into the weeds here. apply does hide a for loop, but lapply does not, at least explicitly. Commented Apr 5, 2018 at 20:17

1 Answer 1

5
L <- lapply(L, function(x){
  colnames(x) <- c("NewName1", "NewName2")
  x
} )
Sign up to request clarification or add additional context in comments.

5 Comments

I think it would be much better if you can provide more explanation about why and how your codes work but his don't.
That makes sense, my only question about the answer is why have the "x" at the end of the function? Thank you for the answer it worked great and I was able to use "do.call("rbind", lapply(L, as.data.frame))" to get the list as one dataset with the changed variables.
@Jake you need to have the x and the end of the function because the anonymous function in lapply needs to return x, otherwise the output won't be the right one.
Alright that makes sense as well. I appreciate the explanation.
I've seen this solution in multiple posts, but i am still confused. Shouldn't I expect to see changed colnames() in each of the dataframes after running this function? Of course, the lapply returns a list, yet even when I convert the list back to a dataframe, the colnames remain the same. Help?

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.