0

I have a very simply question about lapply. I am transitioning from STATA to R and I think there is some very basic concept that I am not getting about looping in R. But I have been reading about it all afternoon and can't figure out a reasonable way to do this very simple thing.

I have three data frames df1, df2, and df3 that all have the same column names, in the same order, etc.

I want to rename their columns all at once.

I put the data frames in a list:

dflist <- list(df1, df2, df3)

What I want the new names to be:

varlist <- c("newname1", "newname2", "newname3")

Write a function that replaces names with those in varlist, and lapply it over the data frames

ChangeNames <- function(x) {
  names(x) <- varlist 
  return(x)
}

dflist <- lapply(dflist, ChangeNames)

So, as far as I understand, R has changed the names of the copies of the data frames that I put in the list, but not the original data frames themselves. I want the data frames themselves to be renamed, not the elements of the list (which are trapped in a list).

Now, I can go

df1 <- as.data.frame(dflist[1])
df2 <- as.data.frame(dflist[2])
df2 <- as.data.frame(dflist[3])

But that seems weird. You need a loop to get back the elements of a loop?

Basically: once you've put some data frames in a list and run your function on them via lapply, how do you get them back out of the list, without starting back at square one?

mechanical_meat
  • 163,903
  • 24
  • 228
  • 223
sam
  • 67
  • 7
  • 1
    I think the more R way to go about it would be to bind the 3 data frames together using something like `bigdf <- dplyr::bind_rows(dflist, .id = "dfid")`, then subset it on the `dfid` column when needed. – Nick DiQuattro Jun 24 '16 at 20:30
  • 1
    If the data.frames have a similar structure, it is a good idea to keep them in a list and work with them from there. See [this post](http://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames) in particular, gregor's answer on why this is a good technique. – lmo Jun 24 '16 at 20:32
  • Thank you Imo for directing me to this answer by gregor. Very helpful. – sam Jun 25 '16 at 21:04

2 Answers2

1

If you just want to change the names, that isn't too hard in R. Bear in mind that the assignment operator, <-, can be applied in sequence. Hence:

names(df1) <- names(df2) <- names(df3) <- c("newname1", "newname2", "newname3")
gung - Reinstate Monica
  • 11,583
  • 7
  • 60
  • 79
0

I am not sure I understand correctly, do you want to rename the columns of the data frames or the components of the list that contain the data frames?

If it is the first, please always search before asking, the question has been asked here.

So what you can easily do in case you have even more data frames in the list is:

# Creating some sample data first
> dflist <- list(df1 = data.frame(a = 1:3, b = 2:4, c = 3:5),
+ df2 = data.frame(a = 4:6, b = 5:7, c = 6:8),
+ df3 = data.frame(a = 7:9, b = 8:10, c = 9:11))

# See how it looks like
> dflist
    $df1
  a b c
1 1 2 3
2 2 3 4
3 3 4 5

$df2
  a b c
1 4 5 6
2 5 6 7
3 6 7 8

$df3
  a  b  c
1 7  8  9
2 8  9 10
3 9 10 11

# And do the trick
> dflist <- lapply(dflist, setNames, nm = c("newname1", "newname2", "newname3"))

# See how it looks now
> dflist

$df1
  newname1 newname2 newname3
1        1        2        3
2        2        3        4
3        3        4        5

$df2
  newname1 newname2 newname3
1        4        5        6
2        5        6        7
3        6        7        8

$df3
  newname1 newname2 newname3
1        7        8        9
2        8        9       10
3        9       10       11

So the names were changed from a, b and c to newname1, newname2and newname3 for each data frame in the list.

If it is the second, you can do this:

> names(dflist) <- c("newname1", "newname2", "newname3")
Community
  • 1
  • 1
panman
  • 1,179
  • 1
  • 13
  • 33
  • Hi. My question was not so much about renaming as about efficiently getting data frames back out of a list after running functions with lapply on them. I just included the rename stuff as that is the particular example I am working with at the moment and I know you are supposed to give very detailed questions. Maybe a better way to say it would be: – sam Jun 25 '16 at 21:07
  • - start with N (potentially large) data frames with similar structure - put them in a list, use lapply to perform operations on all of them (renaming, cleaning, recoding, etc.) - then I want to return to having them as data.frames so i can perform analysis on them individually/heterogeneously. how do i get the cleaned elements of the list out of the list and back as regular data.frames (as it was in the beginning) The gregor post that Imo directed me to suggests that I should just not worry about it and keep everything in lists the whole time. – sam Jun 25 '16 at 21:11