3

I have multiple dataframes saved in a list object. They share the same two column names. I'd like to rename the second column to the name of the dataframe.

Example Data:

df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40) 
df3 <- data.frame(A = 31:40, B= 41:50)
df4 <- data.frame(A = 51:80, B = 61:70) 

listDF <- list(df1, df2,df3, df4)

I'm trying to use lapply to rename the second column to match the name of the dataframe.

# trying to rename second column after the element of the list they're located in
listDF_2 <- lapply(names(listDF), function(x) setNames(listDF[[x]], x) )
starball
  • 20,030
  • 7
  • 43
  • 238
user6883405
  • 393
  • 3
  • 14
  • Your list doesn't look like it has names. What does `names(listDF)` return for you? After you make the listDF, it doesn't keep track of the names "df1", "df2", etc anymore. At least not how you have it written. – MrFlick Jul 12 '18 at 21:20

2 Answers2

4

You may like to use dplyr::bind_rows in this case. It simplifies using name of the data.frames as a new column in combined data frame.

# Create list as.
listDF <- list(df1 = df1, df2 = df2,df3 = df3, df4 = df4)

library(dplyr)

# Now combine all data frames. The name of data frame will be in 'DF_Name' column
bind_rows(listDF, .id = "DF_Name")

#    DF_Name  A  B
# 1      df1  1 11
# 2      df1  2 12
# 3      df1  3 13
# 4      df1  4 14
# 5      df1  5 15
# 6      df1  6 16
# 7      df1  7 17
# 8      df1  8 18
# 9      df1  9 19
# 10     df1 10 20
# 11     df2 21 31
# 12     df2 22 32
# 13     df2 23 33
#.................
#.................
# 58     df4 78 68
# 59     df4 79 69
# 60     df4 80 70

Note: As @Moody_Mudskippe has pointed out that one can simply use

listDF <- lst(df1, df2, df3, df4)

and then use dplyr::bind_rows.

MKR
  • 19,739
  • 4
  • 23
  • 33
  • 1
    @Moody_Mudskipper Ohh. You are correct. Now I have realized what you meant to point out. – MKR Jul 12 '18 at 22:08
2

To keep track of names, you can use:

listDF <- list(df1 = df1, df2 = df2, df3  = df3, df4 = df4)

Then you can use for loop:

for (i in names(listDF)){
  colnames(listDF[[i]]) <- c("A", i)
}

Or if you need to use lapply, you may use this:

newDF <- lapply(names(listDF), function(x){
  colnames(listDF[[x]]) <- c("A", x)
  listDF[[x]]
})
names(newDF) <- names(listDF)